2009-08-18 3 views
1

Когда я получаю предупреждение о памяти, я выпускаю кучу объектов, хранящихся в NSMutableArray.установка объектов на ноль при освобождении NSArray

[_children release]; 

мне также нужно рекурсия через объекты в каком-то момент (возможно после предупреждения ает произошло), так что мне нужно проверить, если объекты все еще вокруг, что я с сравнением с нилью который ISN» t будет работать, потому что освобождение массива ничего не значит.

Я не могу пройти через массив, удаляя объекты 1-на-1 и устанавливая на нуль, потому что мне не разрешено изменять массив во время итерации.

Похоже, что мне не хватает чего-то очевидного. Я просто хочу выпустить + nil некоторые значения в массиве.

ответ

5

Извините, но то, что вы делаете, кажется бессмысленным для меня. Вы не можете установить объект в nil, вы можете установить ссылку на объект на ноль, но это влияет на другие ссылки.

NSObject * a = [[NSObject alloc] init]; 
NSObject * b = a; 

[a release]; 
a = nil; 

// b is NOT nil! b still points to the memory location where 
// a used to be, which is now not valid anymore and using b 
// for anything may crash your application! 

Если я ставлю «а» в массив, а затем удалить его снова из массива, в сохранить отсчет «а» уменьшается на единицу. Либо он тогда еще больше нуля, и в этом случае «а» не будет выпущен, либо он равен нулю, и в этом случае он будет выпущен. Установка ссылки на нуль после ее выпуска не влияет на другие переменные, все еще указывающие на «a».

Таким образом, даже если NSArray установил ссылку на «a» на nil после удаления его в массив и освобождения его (потому что его счетчик ссылок получил нуль), он не будет влиять на переменную экземпляра, все еще указывая на «a ».

Я не уверен, что вы пытаетесь сделать, и это, безусловно, возможно, но вы на совершенно неправильном пути здесь.

+0

Спасибо за разъяснение. Я * был ошибочным и нашел обходное решение. Я из C++-фона, так что это не сразу стало очевидным. В вашем примере я бы предположил b == nil – Sam

+1

Поскольку я не знаю, что вы на самом деле делаете, я не мог бы предложить лучшее решение. Если объекты в массиве являются вашими собственными классами, вы можете, конечно, переопределить метод dealloc (который вызывается, когда удержанный счетчик достигает нуля), и там сообщают другие объекты (например, делегаты или просто передают уведомление), которые вы сейчас собираетесь, так что все другие объекты могут обновить свои ссылки на вас до нуля. – Mecki

+0

Даже в C++, если у вас есть указатель на объект, адрес, который вы держите, не будет очищен, когда сам объект был уничтожен - у вас будет неправильный указатель, точно так же, как Objective-C, когда значение удержания падает до 0 и у вас все еще есть ссылка, указывающая на то, где была выделена память ... –

0

Предполагая, что вы не сохраняете элементы массива в другом месте, конечно, удалив объект из массива или освободив сам массив, вы также освобождаете элемент (ы). Я думаю, это столько, сколько вам нужно.

Из документации Apple:

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

+0

Но откуда я узнал, что он был выпущен? Я не могу запросить его, так как он не существует, и он оставляет меня с висящим указателем ... – Sam

+0

Потому что Apple API так говорит. В нем говорится, что если вы удалите объект из массива или освободите массив - объект WILL будет выпущен. – teabot

+0

Вы неправильно поняли - я не могу сделать, если (appleAPISaysThisObjectIsReleasedOrNot()) во время выполнения. Я нашел обходное решение, так что спасибо в любом случае. – Sam

 Смежные вопросы

  • Нет связанных вопросов^_^