Если я попытаюсь запустить следующий код:
photographer = photographer
Я получаю сообщение об ошибке:
Назначение свойства самому себе.
Я хочу присвоить это свойство самому себе для принудительного запуска блока photographer
didSet
.
Здесь реальный пример: в лекции "16. Segues and Text Fields" "Зимний 2013 курс Стэнфорда iOS" (13): 20), профессор рекомендует написать код, похожий на следующий:
@IBOutlet weak var photographerLabel: UILabel!
var photographer: Photographer? {
didSet {
self.title = photographer.name
if isViewLoaded() { reload() }
}
}
override func viewDidLoad() {
super.viewDidLoad()
reload()
}
func reload() {
photographerLabel.text = photographer.name
}
Примечание. Я внесла следующие изменения: (1) код был переключен с Objective-C на Swift; (2), потому что в Swift я использую блок didSet
этого свойства вместо метода setPhotographer:
; (3) вместо self.view.window
Я использую isViewLoaded
, потому что первый ошибочно заставляет просмотр загружаться при доступе к свойству view
; (4) метод reload()
(только) обновляет ярлык для целей простоты и потому, что он более точно напоминает мой код; (5) добавлена метка фотографа IBOutlet
для поддержки этого более простого кода; (6), поскольку я использую Swift, проверка isViewLoaded()
больше не существует просто по соображениям производительности, теперь требуется предотвратить сбой, поскольку IBOutlet определяется как UILabel!
, а не UILabel?
, поэтому попытка доступа он перед загрузкой представления приведет к сбою приложения; это не было обязательным в Objective-C, поскольку он использует шаблон нулевого объекта.
Причина, по которой мы дважды вызываем перезагрузку, состоит в том, что мы не знаем, будет ли свойство задано до или после создания представления. Например, пользователь может сначала установить свойство, затем представить контроллер представления или представить контроллер представления, а затем обновить свойство.
Мне нравится, как это свойство агностически связано с загрузкой представления (лучше не делать никаких предположений о времени загрузки просмотров), поэтому я хочу использовать тот же шаблон (только слегка измененный) в моем собственном коде:
@IBOutlet weak var photographerLabel: UILabel?
var photographer: Photographer? {
didSet {
photographerLabel?.text = photographer.name
}
}
override func viewDidLoad() {
super.viewDidLoad()
photographer = photographer
}
Здесь вместо создания нового метода, который нужно вызывать из двух мест, я просто хочу код в блоке didSet
. Я хочу, чтобы viewDidLoad
принудительно вызывал didSet
, поэтому присваиваю свойство самому себе. Однако Свифт не позволяет мне это делать. Как я могу заставить didSet
вызываться?