Objective-C: установка автоматически выпущенных объектов на ноль - PullRequest
3 голосов
/ 05 июля 2010

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

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

Ответы [ 2 ]

15 голосов
/ 05 июля 2010

Я думаю, что вы упускаете что-то довольно фундаментальное. Установка объекта на nil ничего не делает для вас с точки зрения управления памятью. Вот что происходит: альтернативный текст http://gallery.me.com/davedelong/100084/Pointers1/web.png?ver=12783505480001

На этом изображении у вас есть стек (где живут ваши локальные переменные; он более или менее синонимичен тому, где вы находитесь в коде во время выполнения). Если вы объявляете что-то вроде int bar = 42;, то bar живет в стеке. Справа у вас куча. Это глобальное пространство памяти, которое принадлежит вашему приложению. Куча была изобретена, чтобы решить проблему области видимости: как заставить полезную информацию жить вне области текущей функции (или метода). Когда мы malloc пробел, нам назначается слот памяти в куче. Когда вы alloc/init объект, этот объект живет в куче. В Objective-C все объекты живут в куче. * Итак, давайте рассмотрим эту строку:

MyObject * foo = [[MyObject alloc] init];

У нас действительно есть две вещи. Во-первых, мы выделили (alloc) новый кусок пространства в куче, достаточно большой, чтобы вместить структуру MyObject. Затем мы взяли расположение этого блока памяти и присвоили его локальной переменной с именем foo. На изображении выше красноватый кружок слева - foo, а красноватый шарик справа - фактический MyObject (вместе со всеми его данными). Имеет смысл пока?

Вот что происходит, когда вы «устанавливаете объект на nil» (foo = nil;) альтернативный текст http://gallery.me.com/davedelong/100084/Pointers2/web.png?ver=12783505490001

Вы увидите, что объект все еще живет в куче . Фактически, единственное, что изменилось, это то, что ваша локальная переменная foo больше не указывает на кусок памяти в куче. Он указывает на 0 (nil, NULL, как вы хотите это называть), и именно так мы указываем, что «это больше не указывает на что-либо значимое».

В двух словах: установка переменной в nil не имеет ничего общего с управлением памятью . Если вы хотите немедленно избавиться от объекта, используйте release, а не autorelease. Однако даже тогда это не гарантированное «немедленное уничтожение», поскольку что-то еще может быть retain объектом (что составляет весь смысл использования модели управления памятью с сохранением-релизом).

Кроме того, как только вы закончите с объектом (и после того, как вы вызовете release или autorelease), все равно будет хорошей идеей установить переменную на nil, просто чтобы избежать потенциальных проблем. , В Objective-C мы можем безопасно отправлять сообщения на номер nil, при этом на наших лицах ничего не возникает (в отличие от Java). Однако, если вы не обнуляете переменную, могут произойти плохие вещи. Допустим, foo указывает на экземпляр MyObject, а затем экземпляр MyObject уничтожается (вы release сделали это, но не установили его на nil). Если вы попытаетесь снова вызвать метод на foo, ваше приложение потерпит крах. Если вы установите foo на nil, тогда ваше приложение продолжит свой веселый путь. Это может не делать то, на что вы надеялись, но это совсем другая проблема.

Добро пожаловать в удивительный мир управления памятью Objective-C.

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

0 голосов
/ 05 июля 2010

Да, это хорошая практика, так как демонстрирует, что объект не используется - то есть никаких ссылочных данных.

Что бы это ни стоило, вы также многое увидите в примере кода от Apple.*

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...