在设备上测试我的应用程序,当我调用自定义对象的副本时,它会返回泄漏,我无法理解为什么。
这是电话:
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;
}
答案 0 :(得分: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:
方法都会在对象中进行,但不会自动释放它,这是copy
方法的预期行为。复制必须像retain或init一样平衡,这意味着你必须在某些时候平衡它与释放。
最后,您的initWithSinglePart:
方法也会泄漏imagePath
。在这种情况下,如果您将imagePath
属性声明为copy
而不是retain
,那么您根本不需要手动执行此操作。然后你只需分配值,让属性设置器为你做。
// Header
@property (copy) NSString *imagePath;
// Now this will do the copy for you
self.imagePath = copyFrom.imagePath;
答案 1 :(得分:1)
此外,属性imagePath
是使用retain
还是copy
语义定义的?
如果需要,您需要在此处添加自动释放:
self.imagePath = [[copyFrom.imagePath copy] autorelease];
因为默认的setter也会保留/复制它。
所以,你要么需要自动释放,要么省略“自我”。绕过默认的setter。
答案 2 :(得分:0)
您正在制作sp
的副本,然后将其添加到阵列中。然后数组保留对象,因此您的保留计数现在为2。
最后释放arr
,从而使其保留计数为1。
您应该向sp
个对象添加其他版本,或者不使用copy
。
试试这个:
self.partList = [NSMutableArray arrayWithCapacity:5];
for (SinglePart *sp in [copyFrom partList]) {
[arr addObject:sp];
}