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

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

0 голосов
/ 12 октября 2010

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

это вызов:

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 ]

4 голосов
/ 12 октября 2010

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 голос
/ 12 октября 2010

Кроме того, свойство imagePath определено с семантикой retain или copy?

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

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

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

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

0 голосов
/ 12 октября 2010

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

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

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

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

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