Analyzer marque une fuite potentielle pour cette construction
-
25-09-2019 - |
Question
Avec le code suivant l'analyseur marque l'appel sélecteur de setMyDict comme une fuite potentielle et dealloc il indique « décrément incorrect du compte de référence n'appartient pas à ce point par l'appelant »
- (id)init {
if (self = [super init]) {
[self setMyDict:[[NSMutableDictionary alloc] init]];
}
return self;
}
- (void)dealloc {
[[self myDict] release];
[super dealloc];
}
@synthesize myDict = _myDict;
Je ne comprends pas. Je pensais qu'avec l'alloc init est l'objet augmente le nombre de retenir par un et le pointeur est stocké dans _myDict par la propriété synthétisée. Si j'utilise à la place de ce code
- (id)init {
if (self = [super init]) {
_myDict = [[NSMutableDictionary alloc] init];
}
return self;
}
- (void)dealloc {
[_myDict release];
[super dealloc];
}
Analyzer ne se plaint pas. Qu'est-ce que je manque?
La solution
Le @synthesize vous fournit un setter et getter pour l'objet que vous la synthèse.
Une méthode de définition ressemble à ceci (extrait de la documentation d'Apple)
-(void)setMyDict:(NSMutableDictionary *)newDict {
if (myDict != newDict) {
[myDict release];
myDict = [newDict retain];
}
}
Vous créez une fuite lorsque vous faites:
[self setMyDict:[[NSMutableDictionary alloc] init]];
Parce que vous ne relâchez le nouveau dictionnaire alloc'd.
Une façon de contourner c'est:
NSMutableDictionary * dict = [[NSMutableDictionary alloc] init];
[self setMyDict:dict];
[dict release];
Cela prend soin de la fuite.
Dans la méthode dealloc, vous devez utiliser:
[myDict release]; // Or whatever your property is called.