2009-03-13 2 views
1

Ich schreibe eine iPhone App. Ich habe eine Header-Datei, die wie folgt aussieht:Warum ist diese Linie von Objective-C undichtem Speicher?


@interface EditTagsViewController : UITableViewController { 
    NSMutableArray *allTags; 
    NSMutableArray *selectedTags; 
    NSInteger currentFavorite; 
} 
@property (nonatomic, retain) NSMutableArray *allTags; 
@property (nonatomic, retain) NSMutableArray *selectedTags; 
@property (nonatomic) NSInteger currentFavorite; 
@end 

In der Implementierungsdatei, mein viewDidLoad Methode sieht wie folgt aus:


- (void)viewDidLoad { 
    NSMutableArray *aTags = [[NSMutableArray alloc] initWithArray:[Tag findAllTags]]; 
    self.allTags = aTags; 
    [aTags release]; 

    NSMutableArray *sTags = [[NSMutableArray alloc] initWithArray:[Tag findByFavoriteId:currentFavorite]]; 
    self.selectedTags = sTags; 
    [sTags release]; 

    UIBarButtonItem *add = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addNewTag:)]; 
    self.navigationItem.rightBarButtonItem = add; 
    [add release]; 
    [super viewDidLoad]; 
} 

Hier ist meine dealloc Methode:


- (void)dealloc { 
    [allTags release]; 
    [selectedTags release]; 
    [super dealloc]; 
} 

Was ist verwirrend für mich ist, dass, wenn ich die App sowohl im Simulator und auf dem Gerät selbst, mit Instrumenten (Speicherlecks) ausführen, sagt mir, dass diese Zeile in meiner ViewDidLoad Methode ein Array leckt:

Es ist verwirrend, weil ich die exakt gleiche Technik mit 2 verschiedenen Variablen verwende, und dennoch wird kein Leck mit dem ersten gemeldet.

Ich fühle mich, als ob ich etwas offensichtliches hier vermisse. Irgendwelche Ideen?

+0

Was genau sagt Ihnen Instruments? Es kann Ihnen im Allgemeinen nur sagen, dass ein Objekt *, das * in einer bestimmten Zeile zugewiesen wurde, durchgesickert ist, aber nicht, dass diese Zeile die Ursache für das Leck ist. Wenn etwas anderes in Ihrem Code das Array überschreibt oder freigibt, kann es auslaufen, aber der Code, den Sie angezeigt haben, wäre nicht verantwortlich. Außerdem sollten Sie eine Eigenschaft nicht unbedingt als änderbar definieren. Dies ermöglicht Verstöße gegen die Kapselung, bei der äußerer Code den Zustand des Objekts hinter seinem Rücken ändern kann. –

Antwort

0

Werfen Sie einen Blick auf findByFavoriteId gibt es eine retain dort? Das ist der einzige Unterschied, den ich zwischen den aTags und sTags in Ihrem Beispiel sehen kann

1

Ihr Code sieht für mich korrekt aus. Ist es möglich, dass einer von [Tag findAllTags] oder [Tag findByFavoriteId:] undicht ist? Stellen Sie sicher, dass self.allTags und self.selectedTags in nil in dealloc festgelegt sind?

Achten Sie auf den Unterschied zwischen den Wörtern self.allTags = ... und allTags = .... Da allTags eine Eigenschaft ist und das Attribut retain hat, ruft es bei jeder Zuweisung über self.allTags = ... implizit die Setter-Methode [self setAllTags:...] auf, die retain auf dem neuen Wert und release auf dem alten Wert (falls vorhanden) aufruft. Sie tun es richtig in diesem Codebeispiel, aber wenn Sie woanders direkt zuweisen allTags (ohne die self.), Sie sind nicht release Ing den alten Wert, der die Quelle des Lecks sein kann. Ebenso für selectedTags.

Verwandte Themen