2010-10-12 2 views
0

Test de mon application sur l'appareil, il retourne une fuite lorsque j'appelle la copie d'un objet personnalisé et je ne comprends pas pourquoi.IPhone - copyWithZone fuite

c'est l'appel:

NSMutableArray *arr = [[NSMutableArray alloc] initWithCapacity:5]; 
for (SinglePart *sp in [copyFrom partList]) { 
    [arr addObject:[sp copy]]; 
} 
self.partList = arr; 
[arr release]; 

c'est la méthode:

- (id)copyWithZone:(NSZone *)zone { 
    SinglePart *copy = [[[self class] allocWithZone:zone] initWithSinglePart:self]; 
    [copy loadImage]; 
    return copy; 
} 

c'est la méthode qui est appelée par copyWithZone:

- (id)initWithSinglePart:(SinglePart *)copyFrom { 
    if (self = [super init]) { 
     self.imagePath = [copyFrom.imagePath copy]; 
     self.color = [UIColor colorWithCGColor:copyFrom.color.CGColor]; 
     self.hasOwnColor = copyFrom.hasOwnColor; 
     self.blendingMode = copyFrom.blendingMode; 
    } 
    return self; 
} 

Répondre

4

copy retourne un nouvel objet avec retain count 1. Cela signifie que vous devez libérer le nouvel objet, ce que vous ne faites pas.

NSMutableArray *arr = [[NSMutableArray alloc] initWithCapacity:5]; 
for (SinglePart *sp in [copyFrom partList]) { 
    SingPart *theCopy = [sp copy]; 
    [arr addObject:theCopy]; 
    [theCopy release]; 
} 
self.partList = arr; 
[arr release]; 

Même votre méthode personnalisée copyWithZone: INIT un objet, mais n'AutoRelease pas, ce qui est le comportement attendu d'une méthode copy. La copie doit être équilibrée de la même manière que retain ou init, ce qui signifie que vous devez l'équilibrer avec release à un moment donné. Enfin, votre méthode initWithSinglePart: fuit aussi le imagePath. Dans ce cas, si vous déclarez la propriété imagePath comme copy au lieu de retain, vous n'avez pas besoin de le faire manuellement. Ensuite, vous affectez simplement la valeur et laissez le configurateur de propriété le faire pour vous.

// Header 
@property (copy) NSString *imagePath; 

// Now this will do the copy for you 
self.imagePath = copyFrom.imagePath; 
+0

Merci beaucoup ... j'ai vraiment besoin de lire un peu plus sur la gestion de la mémoire. Pouvez-vous suggérer un lien? :) – w4nderlust

+1

http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html –

0

Vous faites une copie de sp puis l'ajouter au tableau. L'ensemble conserve alors l'objet de sorte que votre compte est maintenant de conserver 2.

En fin de compte vous relâchez arr, rendant ainsi le nombre de conserver c'est des éléments 1.

Vous devez soit ajouter une autre version aux sp objets, ou ne pas utiliser copy.

Essayez ceci:

self.partList = [NSMutableArray arrayWithCapacity:5]; 
for (SinglePart *sp in [copyFrom partList]) { 
    [arr addObject:sp]; 
} 
1

En outre, la propriété est définie imagePath avec retain ou copy sémantique?

Si oui, vous devez ajouter un autorelease ici:

self.imagePath = [[copyFrom.imagePath copy] autorelease]; 

parce que le setter par défaut conservera/copier aussi. Donc, soit vous devez libérer automatiquement, ou omettre le "soi". pour contourner le setter par défaut.