Рекомендуется декларировать свойства для всех ваших IBOutlets для ясности и последовательности.
Подробности изложены в Руководство по программированию управления памятью . Основная суть в том, что когда ваши объекты NIB разархивированы, загрузочный код nib будет проходить и устанавливать все IBOutlets с помощью setValue: forKey :. Когда вы объявляете поведение управления памятью в свойстве, нет ничего загадочного в том, что происходит. Если представление выгружается, но вы использовали свойство, которое было объявлено как retain, у вас все еще есть действительная ссылка на текстовое поле.
Возможно, более конкретный пример будет полезен, чтобы указать, почему вы должны использовать сохраняющее свойство:
Я собираюсь сделать некоторые предположения относительно контекста, в котором вы работаете, - я предполагаю, что UITextField выше является подпредставлением другого представления, которое контролируется UIViewController. Я предполагаю, что в какой-то момент представление не отображается (возможно, оно используется в контексте UINavigationController), и в какой-то момент ваше приложение получает предупреждение о памяти.
Итак, предположим, что вашему подклассу UIViewController необходим доступ к его представлению для отображения на экране.
На этом этапе файл пера будет загружен, и каждое свойство IBOutlet будет установлено с помощью кода загрузки пера, используя setValue: forKey :. Важные из них, на которые следует обратить внимание, - это представление верхнего уровня, для которого будет установлено свойство представления UIViewController (которое сохранит это представление верхнего уровня), и ваш UITextField, который также будет сохранен. Если он просто установлен, на него будет наложено сохранение с помощью кода загрузки пера, иначе свойство сохранит его. UITextField также будет подпредставлением UIView верхнего уровня, поэтому он будет иметь дополнительное сохранение в нем, находясь в массиве subviews представления верхнего уровня, поэтому на данный момент текстовое поле было сохранено дважды.
В этот момент, если вы хотите программно переключить текстовое поле, вы можете сделать это. Использование этого свойства делает управление памятью более понятным; Вы просто устанавливаете свойство с новым автоматически выпущенным текстовым полем. Если вы не использовали это свойство, вы должны не забыть его освободить и при желании сохранить новое. На данный момент несколько двусмысленно относительно того, кому принадлежит это новое текстовое поле, потому что семантика управления памятью не содержится в установщике.
Теперь предположим, что в стек контроллера UINavigation помещен другой контроллер представления, так что это представление больше не находится на переднем плане. В случае предупреждения памяти, вид этого контроллера за пределами экрана будет выгружен. На этом этапе свойство view верхнего уровня UIView будет обнулено, оно будет освобождено и освобождено.
Поскольку UITextField был задан в качестве свойства, которое было сохранено, UITextField не освобождается, так как было бы только его сохранение - массива subviews представления верхнего уровня.
Если бы вместо этого переменная экземпляра для UITextField не была установлена через свойство, она также была бы рядом, потому что код загрузки пера сохранил ее при установке переменной экземпляра.
Один интересный момент, который это подчеркивает, заключается в том, что, поскольку UITextField дополнительно сохраняется через свойство, вы, вероятно, не захотите хранить его в случае предупреждения памяти. По этой причине вы должны обнулять свойство в методе - [UIViewController viewDidUnload]. Это избавит от окончательного выпуска на UITextField и освободит его, как и предполагалось. Если вы используете это свойство, вы должны помнить, что оно должно быть открыто. Хотя эти два действия функционально эквивалентны, намерение различно.
Если вместо замены текстового поля вы решили удалить его из представления, возможно, вы уже удалили его из иерархии представления и задали для свойства значение nil, или освободили текстовое поле. Хотя в этом случае можно написать правильную программу, легко допустить ошибку чрезмерного освобождения текстового поля в методе viewDidUnload. Чрезмерное освобождение объекта является ошибкой, вызывающей сбой; Установка свойства, которое уже равно nil, равно nil.
Мое описание, возможно, было слишком многословным, но я не хотел опускать какие-либо детали в сценарии. Простое следование рекомендациям поможет избежать проблем, поскольку вы сталкиваетесь с более сложными ситуациями.
Стоит также отметить, что поведение управления памятью в Mac OS X на рабочем столе отличается. На рабочем столе установка IBOutlet без установщика не сохраняет переменную экземпляра; но снова использует сеттер, если он доступен.