Уничтожение NSMutableArray

У меня есть массив NSMutableArray со счастливыми объектами. Эти объекты злобно включают (утечка) меня всякий раз, когда я пытаюсь очистить массив от всех объектов и повторно заселить его.

Он выделяется в функции init так:

self.list = [NSMutableArray array];

Различные методы, которые я использовал для его очистки, включают:

self.list = nil;
self.list = [NSMutableArray array];

и

[self.eventList removeAllObjects];

Явное распределение и освобождение массива также не работает. Утечка ТОЛЬКО возникает, когда я пытаюсь выполнить reset список.

Мне не хватает шага при сбросе или это другая проблема?

Ответы

Ответ 1

Как вы создали объекты, которые протекают? Если вы сделали что-то вроде этого:

- (void)addObjectsToArray {

    [list addObject:[[MyClass alloc] init];

    OtherClass *anotherObject = [[OtherClass alloc] init];
    [list addObject:anotherObject];
}

тогда вы пропустите два объекта, когда список будет освобожден.

Вы должны заменить любой такой код:

- (void)addObjectsToArray {

    MyClass *myObject = [[MyClass alloc] init];
    [list addObject:myObject];
    [myObject release];

    OtherClass *anotherObject = [[OtherClass alloc] init];
    [list addObject:anotherObject];
    [anotherObject release];
}

Подробнее:

Если вы следуете первому шаблону, вы создали два объекта, которые в соответствии с Cocoa правилами управления памятью, которыми вы владеете. Это ваша ответственность за отказ от владения. Если вы этого не сделаете, объект никогда не будет освобожден, и вы увидите утечку.

Вы не видите утечку немедленно, потому что вы передаете объекты массиву, который также принимает на себя ответственность за них. Утечка будет распознаваться только тогда, когда вы удаляете объекты из массива или когда сам массив освобождается. Когда происходит одно из этих событий, массив отказывается от владения объектами, и они останутся "живыми" в вашем приложении, но у вас не будет ссылок на них.

Ответ 2

Вы имеете в виду объекты в массиве утечки?

Как вы добавляете объекты в массив? Массив сохранит их, поэтому вам нужно автоповторить или отпустить их после добавления их в массив. В противном случае после освобождения массива объекты все равно будут сохранены (просочились).

MyEvent *event = [[MyEvent alloc] initWithEventInfo:info];
[self.eventList addObject:event];
[event release];

MyEvent *otherEvent = [[[MyEvent alloc] initWithEventInfo:otherInfo] autorelease];
[self.eventList addObject:otherEvent];

Ответ 3

Как выглядит ваше объявление @property? вы синтезируете аксессоры? Если это так, вам нужно @property(retain). Я предполагаю, что когда вы говорите, что объекты включаются в вас, вы имеете в виду дамп ядра (EXC\_BAD\_ACCESS).

Ответ 4

Я бы сказал, что на самом деле у меня недостаточно информации, чтобы дать вам отличный ответ. Вы говорите, что NSMutableArray по-прежнему выделен, но пуст и не имеет в нем никаких объектов, но объекты, ранее существовавшие ранее в массиве, все еще выделены, хотя они должны быть удалены в этот момент в приложении?

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

Я бы сказал, чтобы помочь вам. Я хотел бы точно знать, что именно говорит MallocDebug, просачивается. Кроме того, @Elfred дает хороший совет по проверке вашего метода @property для массива, действительно его нужно сохранить или скопировать.

Ответ 5

Если утечка возникает только при попытке reset списка, у вас есть кто-то/что-то еще, используя те другие объекты, которые вы только что пытались освободить.