2010-10-12 101 views
0

在設備上測試我的應用程序它返回一個泄漏時,我打電話給自定義對象的副本ande我無法理解爲什麼。iPhone - copyWithZone泄漏

這是調用:

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

這是該方法:

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

這是受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; 
} 

回答

4

copy返回一個新的對象保留數爲1.意思是你需要釋放你不在做的新對象。

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

即使您的自定義copyWithZone:方法inits一個對象,但不會自動釋放它,這是一個copy方法的預期行爲。複製必須像保留或初始化那樣平衡,這意味着您必須在某個時刻平衡它與發佈。

最後,您的initWithSinglePart:方法也會泄漏imagePath。在這種情況下,如果您聲明imagePath屬性爲copy而不是retain,則根本不需要手動執行此操作。然後,您只需分配值並讓屬性設置器爲您完成。

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

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

非常感謝......我真的需要進一步瞭解內存管理。你能建議一些鏈接嗎? :) – w4nderlust 2010-10-12 16:48:36

+1

http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html – 2010-10-12 16:52:50

0

您正在複製sp,然後將其添加到數組中。該陣列然後保留對象,以便您保留計數現在2.

是在你釋放arr末,從而使得它的保留計數的項目1.

您應該另一版本添加到sp對象,或不使用copy

試試這個:

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

而且,與retaincopy語義定義的屬性imagePath

如果是這樣你需要在這裏添加一個自動釋放:

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

,因爲默認的setter將保留/太複製。

所以,你需要自動釋放,或者省略「自我」。繞過默認的setter。