За пределами NARC: когда сохранять, когда назначать, когда копировать - PullRequest
3 голосов
/ 19 июля 2010

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

С другой стороны, я не могу обернуть голову, нужно ли retain (обычно с использованием retain свойств) или просто assign переменных экземпляра. Есть ли там какие-то правила? Я знаю только два:

  1. Если я создал экземпляр в своем классе (например, в init), то я должен сохранить его и выпустить в dealloc.
  2. Делегаты назначаются, а не сохраняются

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

Я видел связанных вопросов , но ничего общего.

Пока я здесь: Как насчет вещей, которые были добавлены в UIWindow или UIView, которые я лично не храню? Если их суперпредставление будет удалено из всех суперпредставлений, будут ли освобождены «естественно» сохраненные экземпляры?

Ответы [ 2 ]

10 голосов
/ 19 июля 2010

Для объектов типа класса вы хотите:

  • retain по умолчанию
  • copy, если класс из изменяемого / неизменяемого кластера классов
  • assign если вам нужно слабые ссылки

Что касается очистки, все свойства retain и copy должны быть released.

Если я сделал экземпляр в своем классе (например, в init), то я должен сохранить его и освободить его в dealloc.

Вопрос не в том, был ли он создан в методе вашего класса, а в том, хотите ли вы:

  • получить сильную ссылку на экземпляр
  • уже владеете им

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

2 голосов
/ 19 июля 2010

как сохранить счет удержания как можно ниже

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

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

Почти во всех случаях вы хотите сохранить или скопировать при назначении переменных экземпляра. Основным исключением является сохранение циклов. Иногда вы попадаете в ситуацию, когда объект A имеет ссылку на объект B, а объект B имеет ссылку на объект A. Если A сохраняет B и B сохраняет A, вы не можете полагаться на обычный шаблон освобождения ссылок в dealloc для создания они уходят. В этой ситуации, как правило, один объект назначается владельцем, а другой - владельцем. В этом случае принадлежащий объект не будет сохранять свою ссылку на владельца.

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

Это очень распространенный шаблон с делегатами для владельца объекта, который устанавливает себя в качестве делегата объекта. Например, контроллер табличного представления часто является также источником данных и / или делегатом табличного представления. Если табличное представление сохранило делегата, у вас был бы цикл сохранения (так как контроллер уже сохранил представление). Вот почему возникла конвенция «делегаты не сохранены».

Вам определенно следует скопировать, если объект, на который вы хотите сослаться, реализует NSCopying, и вам нужно, чтобы он не изменялся, пока вы являетесь владельцем. Пример из Какао - ключи элементов в NSDictionary. Если бы ключи были изменены в словаре, это было бы катастрофой. Поэтому NSDictionary копирует свои ключи.

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

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

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