Подтвердить что ты не робот

Почему нельзя назначить @IBOutlet let вместо var в Swift?

Я следую учебнику по Swift, и я заметил, что при объявлении переменной @IBOutlet автор использует var вместо let. Поэтому мне стало любопытно, почему я не могу использовать let, потому что свойства объекта все еще изменяемы, даже если объект является постоянным или это не так?

Ошибка Xcode показывает, что при использовании let есть

Атрибут

@IBOutlet требует, чтобы свойство изменялось.

но я запутался, потому что questionLabel - это объект UILabel и не обязательно свойство объекта. Или объект questionLabel является свойством текущего viewController?

import UIKit

class ViewController: UIViewController {

    @IBOutlet let questionLabel: UILabel!

}

Заранее благодарим вас за анализ.

4b9b3361

Ответ 1

Отмеченные свойства @IBOulet, как правило, являются свойствами ViewController, которые связаны с помощью построителя интерфейса. Представление, которое вы создаете в построителе интерфейса, должно фактически связывать элементы интерфейса в нем со свойствами во время фактического времени выполнения приложения.

По этой причине он сначала создает новый ViewController с использованием некоторого init без подключения каких-либо элементов интерфейса. Они только подключаются на более позднем этапе. Для того чтобы среда выполнения могла подключать свойства до элементов вида после завершения создания объекта, они не могут быть константами, они должны быть изменены. Поскольку после завершения инициализатора они не имеют значения, они должны быть дополнительными. И чтобы не использовать впоследствии громоздкие свойства, они неявно разворачиваются, поэтому вам не нужно писать label!.property, но label.property хватает.

Вот почему ваш код сработает, как только вы попытаетесь что-то сделать с переменной IBOutlet, которую вы не смогли подключить, и это также является причиной, по которой вы не можете использовать/изменять/манипулировать этими полями в инициализаторе.

Относительно вашей фактической путаницы var/let. Да, сам объект, на который ссылается с помощью let, может быть изменен, например. text a UILabel, но фактическая ссылка на объект не может быть изменена. Это означало бы, что если вы не дадите константу определенное значение в инициализаторе, оно навсегда останется nil.

Ответ 2

По той простой причине, что он не назначен во время инициализации (в методах initXXX), но позже, когда просмотр загружается.

Компилятор фактически не может даже быть уверенным, что переменная когда-либо назначается, потому что загрузка вида является динамически комедийной.

Ответ 3

В быстрых, все vars и let можно рассматривать как свойства.

Свойство неизменное (константа), если оно объявлено с помощью let. Он изменен (переменная), если он объявлен с использованием ключевого слова var. Это , определяющее разницу между let и var.

Выходы должны быть изменены, потому что их значение не будет установлено до тех пор, пока объект не будет инициализирован. (Контроллер представления инициализируется, и его розетки не загружаются сразу.)

Ответ 4

Вы правы questionLabel является объектом типа UILabel, но используется как свойство вашего class ViewController. Вот почему у вас есть @IBOutlet attribute requires property to be mutable. Если вы используете var, вы говорите, что свойство изменено. Если вы используете let, вы говорите, что свойство является неизменным.

Попробуйте создать questionLabel без @IBOutlet и посмотреть, что происходит. Возможно, вы можете положить впереди.

Ответ 5

Сначала создается ViewController, затем создается дерево представления. Это означает, что когда ViewController завершил его init, эти представления еще не существуют. Они будут добавлены непосредственно перед viewDidLoad путем анализа XML-подобных данных раскадровки или XIB.

Я знаю, что это Apple по умолчанию делает что-то, но я всегда буду писать свои ролики, например:

@IBOutlet let questionLabel: UILabel?

По простой причине это абсолютно не доказано, что эта метка будет действительно существовать во время выполнения. Например, при повторном использовании ViewControllers на нескольких экранах изменение макета после установки соединений и т.д. Эта розетка может не быть установлена. Если вы используете questionLabel, который определяется как UILabel!, и это будет nil, ваше приложение выйдет из строя. Я не думаю, что приложения в производстве должны когда-либо рушиться над чем-то таким глупым.

Для реальной безопасности приложений единственным способом узнать, действительно ли он существует, является создание вашего пользовательского интерфейса в коде. Но простота использования раскадровки для одного из экранов действительно заманчива, я все еще использую их много.