Я обычно освобождаю объект после использования
[myObject release];
Но я нашел в некоторых онлайн-уроках, что они назначают nil после отпускания объекта. Как
[myObject release];
myObject = nil;
Требуется ли?
Я обычно освобождаю объект после использования
[myObject release];
Но я нашел в некоторых онлайн-уроках, что они назначают nil после отпускания объекта. Как
[myObject release];
myObject = nil;
Требуется ли?
Это долгая дискуссия о том, нужна ли установка указателя на nil
после освобождения, но я склоняюсь к тому, что это хорошая идея.
После того, как объект будет выпущен, указатель, который вы удерживаете на нем, по-прежнему указывает на то же место. Если ваш релиз взял счетчик удержания до 0, объект будет освобожден. Если вы затем попытаетесь отправить сообщение на освобожденный объект, вы получите ошибку EXC_BAD_ACCESS. Однако отправка сообщения указателю после того, как он был установлен на nil
, не будет ошибкой - он ничего не сделает.
Другая сторона аргумента состоит в том, что если вы отправляете сообщение об освобожденном объекте, хорошо знать об этом и исправить свой код, чтобы убедиться, что этого не происходит.
В обоих лагерях есть умные люди.
Нет, это не обязательно.
Если ваш код хорошо структурирован, нет необходимости принуждать myObject
к нулю.
Однако это может быть хорошей привычкой: release
не сразу уничтожает объект, просто уменьшает счетчик retain
. Таким образом, может быть, что даже если вы вызываете release, объект все равно будет там некоторое время, создавая проблемы, если вы попытаетесь отправить его сообщениям.
Использование myObject = nil;
устраняет эту проблему, так как даже если вы отправляете сообщение на myObject
, ничего не произойдет.
Это не требуется, но в основном проблема стиля. Присвоение nil
после освобождения гарантирует, что вы не можете случайно использовать освобожденную ссылку еще раз (что может или не может привести к сбою). Просто вызов release
в ссылке может привести к тому, что основная память исчезнет. Однако указатель будет по-прежнему указывать на (теперь потенциально недействительный) адрес, а результат последующего вызова метода с использованием этого указателя undefined.
Нет, это не требуется.
Это вещь безопасности. Если у вас есть
[myObject release];
а затем в другом месте вы
[myObject doSomething];
Тогда у вас появятся проблемы.
Если у вас
[myObject release];
myObject = nil;
а затем в другом месте вы
[myObject doSomething];
Тогда ничего не произойдет, потому что вы вызываете объект nil. Таким образом, ваше приложение не просто упадет в большой куче. Или если у вас есть где-то еще в коде
[myObject release];
Затем он будет выпущен на ноль-объекте и поэтому не будет перевыпускать.
Очевидно, вам следует просто не называть объект, который вы уже выпустили!
Я всегда был бы нулевым.
Яблоко себя иногда (задокументировано) проверяет на отсутствие.
Пример
Если вы установите для параметра navigationItem.titleView
значение nil
, чтобы вернуться к использованию navigationItem.title
, или ваш заголовок не будет отображаться.
В документации Apple есть много ссылок на эту "проверку нуля".
Ссылка
Восстановление navigationItem.title после удаления navigationItem.titleView
не очень, но лучше использовать его для предотвращения ошибок...
если вы вызываете где-то в свой код myObject, когда он был выпущен, он дает вам плохую ошибку, но если он будет установлен на ноль, ошибка может быть обходится
если вы попытаетесь:
myObject.someProperty = 1;
или
if (myObject) {...}
и вы только что выпустили myObject, это просто может привести к сбою вашего приложения...
Это не требуется, но обычно считается хорошей практикой во всех средах, за исключением того, что он обычно считается ненужным в методе -dealloc
.
Причина, по которой обычно устанавливается указатель объекта на nil после выпуска, потому что диспетчер методов Objective-C не пытается отправить сообщение объекту nil, что означает, что вы можете случайно использовать объект позже.
после выпуска abject, но не назначает NULL, он сохраняет адрес, но контент освобождается. Таким образом, теперь он не указывает на какое-либо допустимое место в памяти. Хранение ptr теперь висит указателем, который, вероятно, имеет адрес, но не указывает на какое-либо действительное место в памяти. поэтому рекомендуется назначить NULL после освобождения выделенной памяти ниже
PTR = NULL;
таким образом, проблема будет виновата.
Я бы предложил гибридный подход. Давайте рассмотрим типичные требования к приложениям:
Хорошим решением является условное назначение:
Это обеспечивает стабильность в производственных сборках, но в режиме отладки любая попытка получить доступ к переменной приведет к краху приложения. Обратите внимание, что вызов release на объекте не гарантирует, что память объекта будет удалена, поэтому необходимо явно установить неправильный указатель.
#ifdef DEBUG
#define RELEASE(obj) [(obj) release]; (obj) = (id)0x20;
#else
#define RELEASE(obj) [(obj) release]; (obj) = nil;
#endif
На Apple Tech Talk я пошел пару лет назад, инженеры Apple обсудили несколько примеров, когда было необходимо назначить nil, но я не могу вспомнить детали, кроме того, что он был внутри dealloc в обсуждаемых случаях, Достаточно сказать, что не правильно говорить, что вам никогда не приходилось это делать или что это плохая практика. Иногда вам нужно. Но в большинстве случаев вам это не нужно. Извините, моя память неясна.