2009-03-13 4 views
1

J'écris une application iPhone. J'ai un fichier d'en-tête qui ressemble à ceci:Pourquoi cette ligne de mémoire de fuite d'Objective-C?


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

Dans le fichier de mise en œuvre, ma méthode de viewDidLoad ressemble à ceci:


- (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]; 
} 

Voici ma méthode dealloc:


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

Qu'est-ce Ce qui me déroute, c'est que lorsque je lance l'application à la fois dans le simulateur et sur l'appareil lui-même, en utilisant Instruments (fuites de mémoire), il me dit que cette ligne dans ma méthode viewDidLoad fuit un tableau:C'est troublant parce que j'utilise exactement la même technique avec 2 variables différentes, et pourtant aucune fuite n'est signalée avec le premier. J'ai l'impression qu'il me manque quelque chose d'évident ici. Des idées?

+0

Qu'est-ce que les Instruments vous disent spécifiquement? Il peut généralement seulement vous dire qu'un objet * alloué * à une ligne particulière a fui, mais pas que cette ligne est la cause de la fuite. Si quelque chose d'autre dans votre code retient trop ou sous-libère le tableau, alors il peut fuir mais le code que vous avez montré ne serait pas responsable. En outre, vous ne devriez pas faire une propriété avec un type mutable. Cela permet des violations de l'encapsulation, où le code externe peut changer l'état de l'objet derrière son dos. –

Répondre

0

Jetez un oeil à findByFavoriteId là est là un retain? C'est la seule différence que je peux voir entre le aTags et sTags sont utilisés dans votre exemple

1

Votre code me semble correct. Est-il possible que l'un des [Tag findAllTags] ou [Tag findByFavoriteId:] fuit? Assurez-vous de définir self.allTags et self.selectedTags à nil dans dealloc?

Soyez conscient de la différence entre dire self.allTags = ... et allTags = .... Parce que allTags est une propriété et a l'attribut retain, chaque fois que vous affectez via self.allTags = ..., il appelle implicitement la méthode Setter [self setAllTags:...], qui appelle retain sur la nouvelle valeur et release sur l'ancienne valeur (le cas échéant). Vous le faites correctement dans cet exemple de code, mais si ailleurs vous attribuez directement à allTags (sans le self.), vous n'êtes pas release l'ancienne valeur, qui peut être la source de la fuite. De même pour selectedTags.