Я разрабатываю исключительно для iOS 5 с использованием ARC. Должен IBOutlet
сUIView
s (и подклассы) быть strong
или weak
?
Последующий:
@property (nonatomic, weak) IBOutlet UIButton *button;
Избавился бы от всего этого:
- (void)viewDidUnload
{
// ...
self.button = nil;
// ...
}
Есть ли проблемы с этим? Шаблоны используются strong
так же, как автоматически создаваемые свойства, которые создаются при подключении напрямую к заголовку из редактора Interface Builder, но почему? UIViewController
Уже есть strong
ссылка на его view
которая сохраняет подвидов.
IBOutletCollection()
не должно бытьweak
, в противном случае он возвращается какnil
.strong
Ответы:
В настоящее время рекомендуемая наилучшая практика от Apple заключается в том, чтобы IBOutlets были сильными, если только слабые не требуются специально, чтобы избежать цикла сохранения. Как упомянул Йоханнес выше, это было прокомментировано в сеансе «Реализация дизайна пользовательского интерфейса в Интерфейсном Разработчике» WWDC 2015, где инженер Apple сказал:
Я спросил об этом в Твиттере инженера из команды IB, и он подтвердил, что strong должен быть по умолчанию и что документы для разработчиков обновляются.
https://twitter.com/_danielhall/status/620716996326350848 https://twitter.com/_danielhall/status/620717252216623104
источник
ВНИМАНИЕ, УСТАРЕВШИЙ ОТВЕТ : этот ответ не актуален в соответствии с WWDC 2015, для правильного ответа обратитесь к принятому ответу (Даниэль Холл) выше. Этот ответ останется для записи.
Суммировано из библиотеки разработчика :
источник
В то время как документация рекомендует использовать
weak
свойства on для подпредставлений, с iOS 6 кажется, что лучше использоватьstrong
(квалификатор владения по умолчанию) вместо этого. Это связано с изменением того,UIViewController
что представления больше не выгружаются.Тем не менее, я разрываюсь между использованием
а также
в iOS 6 и после:
Использование
weak
четко заявляет, что контроллер не хочет владеть кнопкой.Но опускание
weak
не повредит в iOS 6 без выгрузки представления и является более коротким. Некоторые могут указать, что это также быстрее, но мне еще не приходилось сталкиваться с приложением, которое слишком медленное из-заweak
IBOutlet
s.Неиспользование
weak
может быть воспринято как ошибка.Итог: Начиная с iOS 6 мы больше не можем ошибаться, если не используем выгрузку представлений. Время вечеринки. ;)
источник
nil
вручную.weak
немного дешевле в ARM64: Dweak
свойства или__weak
переменные экземпляра - это путь. Я просто хотел отметить, что здесь меньше ошибок. Что касаетсяweak
того, чтобы быть дешевле на arm64, я даже не видел реальной проблемы с производительностью сweak
IBOutlet
s на armv7. :)strong
имеет смысл.strong
вредно, только если вы используете разгрузку вида - но кто это делает в наши дни? :)Я не вижу никаких проблем с этим. До ARC, я всегда делал свои IBOutlets
assign
, так как они уже сохранены их суперпредставлениями. Если вы делаете ихweak
, вам не нужно обнулять их в viewDidUnload, как вы указали.Одно предостережение: вы можете поддерживать iOS 4.x в проекте ARC, но если вы это сделаете, вы не сможете использовать его
weak
, поэтому вам придется сделать этоassign
, и в этом случае вы все равно захотите обнулить ссылку,viewDidUnload
чтобы избежать свисающий указатель. Вот пример ошибки с висящим указателем, с которой я столкнулся:UIViewController имеет UITextField для почтового индекса. Он использует CLLocationManager для обратного геокодирования местоположения пользователя и установки почтового индекса. Вот обратный вызов делегата:
Я обнаружил, что если я отклонил это представление в нужное время и не установил self.zip
viewDidUnload
, обратный вызов делегата может вызвать исключение неправильного доступа к self.zip.text.источник
weak
Насколько я понимаю, свойства не нужно превозноситьviewDidUnload
. Но почему шаблон Apple для создания торговых точек включает в себя[self setMySubview:nil]
?IBOutlet
должен быть сильным по причине производительности. См. Справочник раскадровки, Сильный IBOutlet, Док сцены в iOS 9Начиная с Xcode 7, он предлагает
strong
Если вы посмотрите сеанс WWDC 2015 407 « Реализация дизайнов пользовательского интерфейса в Интерфейсном Разработчике» , он предлагает (стенограмма с http://asciiwwdc.com/2015/sessions/407 )
источник
В разработке для iOS загрузка NIB немного отличается от разработки для Mac.
В разработке для Mac IBOutlet обычно является слабой ссылкой: если у вас есть подкласс NSViewController, будет сохранено только представление верхнего уровня, а когда вы освободите контроллер, все его подпредставления и выходы будут автоматически освобождены.
UiViewController использует Key Value Coding для установки выходов, используя сильные ссылки. Поэтому, когда вы освобождаете свой UIViewController, вид сверху будет автоматически освобожден, но вы также должны освободить все его выходы в методе dealloc.
В этом посте из ранчо «Большой ботаник» они освещают эту тему, а также объясняют, почему использование надежной ссылки в IBOutlet не является хорошим выбором (даже если в этом случае Apple рекомендует).
источник
Я хотел бы отметить одну вещь: несмотря на то, что инженеры Apple заявили в своем видео WWDC 2015 здесь:
https://developer.apple.com/videos/play/wwdc2015/407/
Apple постоянно меняет свое мнение по этому вопросу, что говорит нам, что нет единого правильного ответа на этот вопрос. Чтобы показать, что даже инженеры Apple разделяют эту тему, взгляните на самый последний пример кода Apple, и вы увидите, что некоторые люди используют слабые, а некоторые нет.
Этот пример Apple Pay использует слабое: версия https://developer.apple.com/library/ios/samplecode/Emporium/Listings/Emporium_ProductTableViewController_swift.html#//apple_ref/doc/uid/TP40016175-Emporium_ProductTableViewController_swE
Как и этот пример «картинка в картинке»: https://developer.apple.com/library/ios/samplecode/AVFoundationPiPPlayer/Listings/AVFoundationPiPPlayer_PlayerViewController_swift.html#//apple_ref/doc/uid/TP40016166-onterL_PlayerPlayPlayPlayPlayPlayPlayD
Как и пример Листера: https://developer.apple.com/library/ios/samplecode/Lister/Listings/Lister_ListCell_swift.html#//apple_ref/doc/uid/TP40014701-Lister_ListCell_swift-DontLinkElementID_57
Как и в примере с Core Location: https://developer.apple.com/library/ios/samplecode/PotLoc/Listings/Potloc_PotlocViewController_swift.html#//apple_ref/doc/uid/TP40016176-Potloc_PotlocViewController_swift-DontLink
Как и пример предварительного просмотра контроллера представления: https://developer.apple.com/library/ios/samplecode/ViewControllerPreviews/Listings/Projects_PreviewUsingDelegate_PreviewUsingDelegate_DetailViewController_swift.html#//apple_ref/doc/uid/TP40016546-Projects_PreviewUsingDelegate_PreviewUsingDelegate_DetailViewController_swift-DontLinkElementID_5
Как и пример HomeKit: https://developer.apple.com/library/ios/samplecode/HomeKitCatalog/Listings/HMCatalog_Homes_Action_Sets_ActionSetViewController_swift.html#//apple_ref/doc/uid/TP40015048-Hont_Slay_Slay_SlaySalogSalog
Все они полностью обновлены для iOS 9, и все используют слабые выходы. Из этого мы узнаем, что А. Проблема не так проста, как это делают некоторые люди. B. Apple неоднократно меняла свое мнение, и C. Вы можете использовать все, что вас радует :)
Особая благодарность Полу Хадсону (автору www.hackingwithsift.com), который дал мне разъяснения и ссылки на этот ответ.
Я надеюсь, что это проясняет тему немного лучше!
Береги себя.
источник
Начиная с WWDC 2015 проводится сеанс « Реализация дизайнов пользовательского интерфейса в Интерфейсном Разработчике» . Примерно через 32 минуты он говорит, что ты всегда хочешь сделать себя
@IBOutlet
сильным .источник
Знайте,
IBOutletCollection
должно быть@property (strong, nonatomic)
.источник
copy
как тоNSArray
?Похоже, что-то изменилось за эти годы, и теперь Apple рекомендует использовать сильный в целом. Свидетельство об их сеансе WWDC находится в сеансе 407. Реализация проектов пользовательского интерфейса в Интерфейсном Разработчике и начинается в 32:30. Моя записка из того, что он говорит (почти, если не совсем, цитирую его):
Выходные соединения в целом должны быть сильными, особенно если мы подключаем подпредставление или ограничение, которое не всегда сохраняется в иерархии представлений.
слабое выходное соединение может понадобиться при создании пользовательских представлений, в которых есть какая-то ссылка на что-то, резервное копирование в иерархии представлений, и в целом это не рекомендуется
В других отделениях он должен быть всегда сильным, пока некоторые из наших пользовательских представлений не создают цикл сохранения с некоторыми представлениями вверх в иерархии представлений.
РЕДАКТИРОВАТЬ :
Некоторые могут задать вопрос. Сохраняет ли это сильную ссылку, не создает ли цикл сохранения, поскольку корневой контроллер представления и собственное представление сохраняют ссылку на него? Или почему это изменилось? Я думаю, что ответ более ранний в этом выступлении, когда они описывают, как перья создаются из XIB. Для VC и для представления создан отдельный кончик. Я думаю, что это может быть причиной, по которой они меняют рекомендации. Тем не менее, было бы неплохо получить более глубокое объяснение от Apple.
источник
Я думаю, что самая важная информация: элементы в xib автоматически попадают в подпредставления представления. Subviews является NSArray. NSArray владеет своими элементами. и т.д. имеют сильные указатели на них. Так что в большинстве случаев вы не хотите создавать другой сильный указатель (IBOutlet)
А с ARC вам не нужно ничего делать в
viewDidUnload
источник