IPhone - копия с утечкой

Тестирование моего приложения на устройстве возвращает утечку, когда я вызываю копию пользовательского объекта, и я не могу понять, почему.

это вызов:

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

3 ответа

Решение

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;

Кроме того, является собственностью imagePath определяется с retain или же copy семантика?

Если это так, вам нужно добавить авто-релиз здесь:

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

потому что установщик по умолчанию также сохранит / скопирует его.

Итак, вам нужно либо выполнить авто-релиз, либо опустить "self". обойти установщик по умолчанию.

Вы делаете копию sp а затем добавить его в массив. Затем массив сохраняет объект, поэтому ваш счетчик хранения теперь равен 2.

В конце концов, вы отпускаете arr, таким образом, сохраняя количество своих предметов 1.

Вы должны добавить еще один релиз к sp объекты или не использовать copy,

Попробуй это:

self.partList = [NSMutableArray arrayWithCapacity:5];
for (SinglePart *sp in [copyFrom partList]) {
    [arr addObject:sp];
}
Другие вопросы по тегам