0

在设备上测试我的应用程序会返回泄漏,而我调用自定义对象的副本并且我不明白为什么。

这是电话:

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

3 回答 3

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方法的预期行为。复制必须像保留或初始化一样平衡,这意味着您必须在某些时候平衡它与释放。

最后,您的initWithSinglePart:方法也会泄漏imagePath。在这种情况下,如果您将imagePath属性声明为copyretain那么您根本不需要手动执行此操作。然后您只需分配值并让属性设置器为您完成。

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

// Now this will do the copy for you
self.imagePath = copyFrom.imagePath;
于 2010-10-12T16:37:57.853 回答
1

另外,属性是用语义imagePath 定义的retain还是copy语义定义的?

如果是这样,您需要在此处添加自动释放:

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

因为默认设置器也会保留/复制它。

因此,您要么需要自动释放,要么省略“自我”。绕过默认设置器。

于 2010-10-12T16:41:33.017 回答
0

您正在制作副本,sp然后将其添加到数组中。然后数组保留对象,因此您的保留计数现在为 2。

最后你 release arr,从而使其项目的保留计数为 1。

您应该向sp对象添加另一个版本,或者不使用copy.

试试这个:

self.partList = [NSMutableArray arrayWithCapacity:5];
for (SinglePart *sp in [copyFrom partList]) {
    [arr addObject:sp];
}
于 2010-10-12T16:38:56.760 回答