Сортировать утечку памяти NSMutableArray

Мой объект имеет частные элементы NSmutableArray. Я использую следующий код для сортировки объектов в элементах по размеру:

-(void)sortItems{
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"size" ascending:YES];    
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray = [items sortedArrayUsingDescriptors:sortDescriptors];
NSMutableArray* newArray = [[NSMutableArray alloc] initWithArray: sortedArray];
[self setItems:newArray];
[sortDescriptor release];   

}

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

NSMutableArray* newArray = [[NSMutableArray alloc] initWithArray: sortedArray];
NSMutableArray* oldArray = [self items];
[self setItems:newArray];
[oldArray release];

Но это дает ошибку EXC_BAD_ACCESS. Я читал об обработке памяти в objC и убежден, что делаю здесь что-то принципиально неправильное.

Любая помощь будет принята с благодарностью!


person JimmyB    schedule 21.02.2012    source источник
comment
Покажите реализацию/декларацию вашего метода setItems. Это должно сохранять newArray, что означает, что вам нужно [newArray release] сразу после его вызова.   -  person trojanfoe    schedule 21.02.2012
comment
на данный момент элементы являются свойством: @property (nonatomic, assign) NSMutableArray *items; Я думаю, мне нужно прочитать, когда использовать «удерживать» в флагах свойств!   -  person JimmyB    schedule 21.02.2012


Ответы (2)


Вы пропускаете новый массив, а не старый:

NSMutableArray* newArray = [[NSMutableArray alloc] initWithArray: sortedArray];
[self setItems:newArray];
[sortDescriptor release];
[newArray release]; // <-- add this

Фундаментальное правило заключается в том, что вы должны освобождать все, что вы выделили, и обычно вы не должны заботиться о сохранении вещей для кого-либо (например, [self setItems:]), те, кому нужно что-то сохранить, сделают это сами.

Я бы также рекомендовал сделать self.items изменяемым массивом и использовать [self.items sortUsingDescriptors:sortDescriptor для сортировки на месте без создания копии.

person hamstergene    schedule 21.02.2012
comment
отличный! большое спасибо. следует ли устанавливать флаги свойств элементов для сохранения, а не для назначения? - person JimmyB; 21.02.2012
comment
@JimmyB Я предполагал, что они уже есть. Да, для этого варианта использования они должны быть. Если ваш объект является владельцем массива, он сохраняет массив. - person hamstergene; 21.02.2012
comment
похоже, что это должно работать, но по какой-то причине добавление этого [выпуска newArray] приводит к сбою приложения еще до того, как оно выполнит эту функцию... очень странно! - person JimmyB; 21.02.2012
comment
@JimmyB Это означает, что проблемы есть где-то еще. Покажите, как было присвоено старое значение items, и места, где оно освобождается/автоматически освобождается, если таковые имеются. - person hamstergene; 21.02.2012
comment
спасибо, я посмотрю на это! кажется, что sortItems успешно работает несколько раз, так что вы правы - проблема должна быть в другом. Спасибо за вашу помощь! - person JimmyB; 21.02.2012
comment
Спасибо за помощь. как оказалось, моя функция инициализации тайлов устанавливала items=.., а не self.items=... спасибо за помощь! - person JimmyB; 22.02.2012

Есть ли причина, по которой вы не можете выпустить newArray в своем первом примере?

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"size" ascending:YES];    
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray = [items sortedArrayUsingDescriptors:sortDescriptors];
NSMutableArray* newArray = [[NSMutableArray alloc] initWithArray: sortedArray];
[self setItems:newArray];
[newArray release];
[sortDescriptor release]; 
person Markus Persson    schedule 21.02.2012