iOS Освобождение объекта слишком рано — возможна путаница с автоматическим освобождением и копированием

Я написал приложение с пользовательским классом поиска. Это создает массив результатов.

Затем я назначаю этот массив моему классу FirstViewController и перезагружаю табличное представление, которому назначен массив результатов.

self.aResults = [thisSearch.aResults copy]
...
[[self searchResults] reloadData];

Вскоре после этого я выпускаю thisSearch

[thisSearch release];

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

Раньше со мной такого не случалось, но я понял, что происходит утечка памяти, поэтому я сошел с ума по авторелизу и добавил много авторелиза в свой Поиск класс. Но не мой класс FirstViewController.

Итак, если я использую Копировать, не создает ли он на самом деле копию объекта, а просто увеличивает счетчик ссылок? Итак, когда я уничтожаю Search, уничтожаю ли я там массив результатов и, следовательно, уничтожаю то, к чему FirstViewController пытается получить доступ для табличного представления?

Извините, если это не имеет особого смысла, я не очень-то себя чувствую сегодня.


person Pete    schedule 01.09.2011    source источник
comment
Вместо self.aResults = [thisSearch.aResults copy] вы должны сделать свойство aResults копируемым, например @property (nonatomic, copy) NSArray *aResults;. Затем, когда вы устанавливаете это свойство, оно автоматически получает копию объекта, для которого вы его устанавливаете. Когда закончите с тем, что находится внутри aResults, выполните self.aResults = nil, и оно будет выпущено. Я не отправил это как ответ, так как это просто совет, но это не причина сбоя вашего приложения. И без дополнительного кода я не знаю, почему это происходит.   -  person Filip Radelic    schedule 01.09.2011


Ответы (1)


Когда вы copy возражаете (а для этого объект должен соответствовать NSCopying протоколу, но это случай NSArray), это точно так же, как если бы вы initиализировали его в первый раз с предопределенными значениями.

Итак, вы несете ответственность за release объекты, которые были copied.

Поэтому вы должны сделать:

self.aResults = [thisSearch.aResults copy]
...

[thisSearch release]; // When you release thisSearch this will not affect aResults
...

// then you can either do:
[self.aResults autorelease]; // but then do not release it later on
// or
[self.aResults release]; // when you're done with it

Однако я сомневаюсь, что это решит ваши проблемы с памятью. Из-за чрезмерного автоматического выпуска (и все еще выпускающего вещи) вы могли полностью испортить управление памятью вашего приложения.

Чтобы попытаться исправить это, попробуйте проанализировать свой проект и посмотреть, что получится.

введите здесь описание изображения

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

person apouche    schedule 01.09.2011
comment
Аааа, надо было запустить Analyze! Я запустил это, и он указал мне на NSDicitonary, который я автоматически выпускал, и сказал мне, что счетчик ссылок уже равен 0, потому что я назначал этот словарь массиву, который также был автоматически выпущен, поэтому я полагаю, что он пытался освободить этот словарь когда массив, в котором он находился, уже исчез - person Pete; 01.09.2011