开发者

IPhone - copyWithZone leak

Testing my app on the device it returns a leak whe i call the copy of a custom object ande i can't understand why.

this is the call:

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

this is the method:

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

this is the method that is called by 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;
 }


copy returns a new object with retain count 1. Meaning you need to release the new object, which you are not doing.

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

Even your custom copyWithZone: method inits an object, but does not autorelease it, which is the expected behavior of a copy method. Copy must be balanced just like a retain or init, meaning you must balance it with release at some point.

Lastly, your initWithSinglePart: method leaks the imagePath as well. In this case if you declare the imagePath property as copy instead of retain then you don't need to do this manually at all. Then you simply assign the value and let the property setter do it for you.

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

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


Also, is the property imagePath defined with retain or copy semantics?

If so you need to add an autorelease here:

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

because the default setter will retain/copy it too.

So, you either need to autorelease, or omit the "self." to bypass the default setter.


You are making a copy of sp and then adding it to the array. The array then retains the object so your retain count is now 2.

In the end you release arr, thus making the retain count of it's items 1.

You should either add another release to the sp objects, or not use copy.

Try this:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜