Свифт, два вопроса. 1) слабый var 2) оператор bang для @IBOutlet
Per:
@IBOutlet weak var nameLabel: UILabel!
-
Всякий раз, когда я объявляю свои IBOutlets, я просто использую var вместо слабого var. Но я недавно столкнулся с несколькими шаблонами кода, которые используют слабый var. Почему они это делают? Какая дополнительная польза?
-
Почему в конце UILabel существует оператор bang. Я знаю, что это требуется, и я иду вместе с ним, но просто прошу об этом сейчас.
Спасибо заранее.
Ответы
Ответ 1
- Swift IBOutlet по умолчанию слабы (но по умолчанию другие свойства по-прежнему сильны). Таким образом, оба письма одинаковы.
У вас есть более подробная информация о различии между слабыми и сильными здесь
- Согласно документация на Apple
Когда вы объявляете розетку в Swift, вы должны указать тип выведите неявно развернутую опциональную (!). Таким образом, вы можете раскадровка соединяет выходы во время выполнения, после инициализации.
Ответ 2
Выходы слабы, поскольку элементы представления принадлежат (сильно) по представлению. Я думаю, что это технически нормально, так как ваш контроллер просмотра также имеет сильную ссылку, но не обязательно.
Слабые переменные являются необязательными, так как они могут быть nil
. Вы можете объявлять свои выходы с помощью ?
вместо этого, но это означает, что каждый раз с помощью принудительного развертывания или необязательной привязки. Объявление их как неявно-развернутых опций с помощью !
является просто удобством.
Ответ 3
Вы используете слабый сигнал, ссылаясь на IBOutlets, потому что пока объект остается в своем супервизоре, он будет иметь для него сильную ссылку. См. слабый или сильный для IBOutlets.
Затем оператор bang указывает, что IBOutlet является явно развернутой меткой. С оператором bang он гарантирует, что объект будет существовать, поэтому, ссылаясь на него, вы можете просто ссылаться на него следующим образом:
someLabel.text = "some text"
Однако вы можете сделать их IBOutlets необязательными:
@IBOutlet weak var someLabel: UILabel?
Но при доступе к ним вы должны использовать ?
someLabel?.text = "some text"
Ответ 4
-
@gregheo ответ лучше всего объясняется, чтобы уточнить: если вы рассматриваете право собственности в этой ситуации, объект View, на который ссылается @IBOutlet
, как правило, не должен принадлежать диспетчеру просмотра, ссылаясь на него.
Скорее, он должен принадлежать его супервину, где бы он ни находился в дереве (что сильно зависит от UIView.subviews
). Контроллер просмотра вместо этого владеет самым корнем из него. Подробное описание Tree Tree (UIViewController.view
). weak
явно объявляет ссылку, не относящуюся к владельцам, которая может стать нулевой в разных точках жизни View Controller.
-
Здесь я бы предложил альтернативу использованию !
: использование неявно разворачиваемой необязательной ссылки - опасная практика, которая ослабляет инструменты, которые предлагает Swift. Контроллер просмотра, который загружается из Xib или Storyboard, включает в свой жизненный цикл регулярное время после его создания и перед тем, как View был загружен, где ссылка @IBOutlet
равна нулю, каждый раз. Предполагать, что в течение этого времени никто не будет действовать на члена, это означает, что мы не используем обратную грамматику Swift и компилятор в наших интересах.
Дополнительно @IBOutlet
- это мощный инструмент, который обеспечивает гибкий, визуально сфокусированный подход при разработке экрана или представления. Обычная практика заключается в том, чтобы ваш контроллер просмотра отображал @IBOutlet
для всей имеющейся у него информации независимо от того, известно ли, что он будет использоваться и по отдельности решит, что на самом деле подключать и использовать при построении и итерации в представлении от в Interface Builder.
Кроме того, если ваш вид должен быть достаточно гибким, чтобы его можно было создать из Xib/Storyboard И из кода, в зависимости от того, как вы решаете, что ссылающиеся вложенные объекты должны быть созданы и подключены, они могут быть или не быть доступны немедленно.
По причинам, указанным выше, я определяю мой: @IBOutlet weak var nameLabel: UILabel?