Если у вас есть IBOutlet, но нет собственности, он сохраняется или нет? - PullRequest
11 голосов
/ 02 апреля 2011

Мне кажется, что документация по этому вопросу неясна:

Скажем, вы работаете с iOS (НЕ для Mac, нет необходимости упоминать различия).Скажем, это строго 4.0+ (не нужно упоминать различия в старых ОС).Скажем, мы загружаем NIB строго автоматически.

Скажем, у вас есть UIViewController, BigView.Скажем, в NIB-файле есть дюжина так называемых «элементов верхнего уровня» ... это могут быть пользовательские элементы управления, изображения или что-то еще.

Скажем, вы определенно собираетесь явно создать и затем избавитьсяBigView несколько раз во время запуска приложения.Итак:

Для одного из этих элементов верхнего уровня в NIB существует три возможности :

(1) У вас нет какого-либо вида IBOutlet для него, вообще.

(2) У вас есть подключенный IBOutlet - но не свойство.

(3) У вас есть подключенное свойство IBOutlet (чтобы избежать путаницы, скажемсвойство сохранения).

Так что же происходит с элементом при выпуске BigView?

В случае (3) кажется очевидным, что вы должны освободить явно.Если вы этого не сделаете, он будет зависать после исчезновения вида.Нет проблем.

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

В случае (2) непонятно, что происходит .......

Глядя на общеизвестную справочную ссылку: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/CocoaNibs.html это очень сомнительно:

"В iOS код загрузки пера использует метод setValue: forKey: для повторного подключения каждой розетки. Этот метод аналогичным образом ищет подходящий метод доступа и [ТАК, ЧТО ПРОИСХОДИТ, ЕСЛИ ЕСТЬ ISN'T ONE ?? TELL US APPLE ...] прибегает к другим средствам, когда это не удается ... [ХОРОШИЙ ГРИФ!] "

И посмотрите эту документацию: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/CocoaNibs.html и прокрутите внизto "Сохранение объектов пера"

Итак ...

"Объекты в файле пера создаются с счетом сохранения 1 и затем автоматически высвобождаются" Fantastic ..

Но подождите!Прочтите несколько слов ...

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

Чтоо чем они говорят?

Имеют ли они в виду, что если нет доступного сеттера (ivar, но нет свойства), то он ОПЯТЬ RETAINED (кроме слова «сохранить», о котором они только что упоминали впредыдущее предложение) --- или они просто повторяются, то есть "сохраняет объект по умолчанию" - это то же самое, что "сохраняют", о котором они говорили ранее ("создано с счетом сохранения 1, а затем автоматически выпущено").

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

Действительно, если кто-то действительно знает ответ на этот вопрос ...... какЗнаете ли вы?!? Вы спрашивали DTS, или через тестирование, или?Я полагаю, ключевая документация (только что вставленная) агрессивно неясна.

Опять же - если у вас есть IBOutlet, , но не свойство , связанное с объектом "верхнего уровня".. вы несете ответственность за его выпуск?Сохранено ли это? в этой ситуации?

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

Вопрос в том, что произойдет, если вы действительно используете IBOutlet iVar, но НЕ свойство ...

Я глупо никогдадумал об этом раньше / предполагал слишком много, есть ли у кого-нибудь решающий ответ?Приветствия !!


Для записи я сделал тестовый проект.

На самом деле (удивительно для меня) просто акт соединения элемента IB с IBOutlet вФакт, видимо, добавляет одно удержание .

(Я могу только предположить из некачественного документа, что в этой ситуации вы получаете конкретно: удержание, автоматическое освобождение, удержание - ведение к одному удержанию на балансе.)1091 * Я опубликую демо-проект.Я также направляю всех читателей на ответ Джоны ниже, который безошибочно объясняет поведение setValue: forKey: Cheers

Ответы [ 3 ]

11 голосов
/ 02 апреля 2011

Я не понимаю, что вызывает такое большое замешательство, я думаю, что документация «Удержание объекта Nib» точно объясняет, что происходит. Давайте разберемся с этим и пройдемся по тому, что происходит:

Объекты в файле пера создаются с счетом сохранения 1 и затем автоматически высвобождаются.

ClassLoadedFromNib *loadedObject = [[[ClassLoadedFromNib alloc] initWithCoder:coder] autorelease];

Однако, перестраивая иерархию объектов, UIKit восстанавливает соединения между объектами, используя setValue: forKey: метод,

[filesOwner setValue:loadedObject forKey:nameOfIBOutlet];

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

Поведение по умолчанию -setValue:forKey: в iOS примерно равно

//lazy pseudocode
if ([self respondsToSelector:@selector(@"setKeyName:")]) {
  [self setKeyName:value];
}
else {
  object_setIvar(self, _keyName, [value retain]);
}

Подробнее об этом см. В руководстве по программированию «ключ-значение». Если только объект владельца вашего файла не переопределит -setValue:forKey: (или +accessInstanceVariablesDirectly и -setValue:forUndefinedKey:), вы не захотите управлять владением объектом, как описано выше.


Если вы определяете выходы для объектов nib-файла, вы всегда должны определять метод установки (или объявленное свойство) для доступа к этому выходу. Методы установки для торговых точек должны сохранять свои значения, а методы установки для торговых точек, содержащих объекты верхнего уровня, должны сохранять свои значения, чтобы предотвратить их освобождение.

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


Если вы не сохраняете объекты верхнего уровня в торговых точках, вы должны сохранить либо массив, возвращенный методом loadNibNamed: owner: options:, либо объекты внутри массива, чтобы предотвратить преждевременное освобождение этих объектов.

Объекты, не подключенные к розеткам, были автоматически освобождены. Сохраните их или массив, возвращенный из -loadNibNamed: owner: options: если вы попытаетесь получить к ним доступ позже.

2 голосов
/ 02 апреля 2011

Это интересный вопрос, но поскольку документация неоднозначна, я думаю, что лучший план (и тот, который, как я считаю, рекомендуется Apple), состоит в том, чтобы все ваши магазины сохранили свои свойства.Вы точно знаете, что происходит в этом случае, и нет особых причин делать что-либо еще.

0 голосов
/ 02 апреля 2011

Случай 1) Если объект ничем не удерживается, он будет освобожден при следующем сливе из пула автоматического выпуска.

Случай 2) В упомянутом выше ответе Джон Хесс уже описал (со ссылкой на документацию) различия между Mac OS X и iOS для этого случая.

Джон Гесс прав или Фримен прав?

В случае iOS и Гесс, и Фримен говорят, что объект будет сохранен. В этом нет никакого противоречия между ними.

Настоятельно рекомендуется использовать методы установки для всех выходов:

Руководство по программированию ресурсов, Nib-файлы

Если вы определяете выходы для nib-файла объекты, вы всегда должны определить метод установки (или объявленное свойство) для доступа к этой розетке. Сеттер методы для торговых точек должны сохранить их ценности ...

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