Если я попытаюсь запустить следующий код:
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 вызываться?