繁体   English   中英

为什么在Swift中不能为@IBOutlet分配let而不是var?

[英]Why can't an @IBOutlet be assigned let instead of var in Swift?

我正在跟踪有关Swift的教程,并且注意到作者在声明@IBOutlet变量时使用var而不是let 因此,我对为什么不能使用let感到好奇,因为即使对象是常量,对象的属性仍然是可变的,或者不是这样吗?

使用let是时的Xcode显示错误

@IBOutlet属性要求属性是可变的

但是我很困惑,因为questionLabelUILabel对象,而不一定是对象的属性。 还是questionLabel对象是当前viewController的属性?

import UIKit

class ViewController: UIViewController {

    @IBOutlet let questionLabel: UILabel!

}

如果我要分析的话,请先谢谢。

@IBOulet标记的属性通常是使用接口构建器连接的ViewController的属性。 您在接口构建器中创建的视图必须在实际应用程序运行时实际将其中的接口元素连接到属性。

因此,它首先使用一些 init创建一个新的ViewController而不连接任何接口元素。 他们仅在以后的阶段建立联系。 为了使运行时能够在对象创建完成之后将属性连接到视图元素,它们不能是常量,它们必须是可变的。 因为在初始化程序完成后它们没有值,所以它们必须是可选的。 而且,为了避免以后麻烦地使用这些属性,它们是隐式展开的可选属性,因此您不必编写label!.propertylabel.property就足够了。

这就是为什么您尝试对无法连接的IBOutlet变量执行操作时代码崩溃的原因,这也是为什么您无法在初始化程序中使用/更改/操作这些字段的原因。

关于您的实际var / let感到困惑。 是的,可以更改使用let引用的对象本身,例如,不能更改实际对象引用的UILabel BUT的text 那意味着如果您在初始化程序中不给常数一个特定的值,它将永远保持nil

出于简单的原因,它不是在初始化期间(在initXXX方法中)分配的,而是在以后加载视图时分配的。

实际上,编译器甚至无法确保曾经分配过该变量,因为视图加载完全是动态的。

快速地,所有的var和let都可以视为属性。

如果用let声明属性,则该属性是不可变的(常量)。 如果使用var关键字声明,则它是可变的(变量)。 那就是letvar之间定义差异。

出口必须是可变的,因为直到初始化对象后,它们的值才会被设置。 (视图控制器已初始化,并且插座没有立即加载。)

没错, questionLabelUILabel类型的对象,但用作class ViewController的属性。 这就是为什么您拥有@IBOutlet attribute requires property to be mutable 如果使用var ,则表示属性是可变的。 如果你使用let你说的属性是不可改变的。

尝试创建没有@IBOutlet然后看看发生了什么。 可能您可以将let放在前面。

首先创建ViewController,然后构建视图树。 这意味着当ViewController完成init这些视图尚不存在。 通过解析情节提要或XIB的类似XML的数据,将它们添加到viewDidLoad之前。

我知道这是Apple的默认处理方式,但我总是会这样写:

@IBOutlet let questionLabel: UILabel?

出于简单的原因,绝对不能证明此标签在运行时确实存在。 例如,当在多个屏幕上重用ViewController时,在设置连接后更改布局等可能未设置此插座。 如果您将使用定义为UILabel!questionLabel UILabel! 这将是nil您的应用程序将崩溃。 我不认为生产环境中的应用程序应该不会因为这样的愚蠢而崩溃。

为了真正的应用安全,真正确定存在的唯一方法是在代码中构建UI。 但是,对于不在屏幕外的情况使用Storyboard的易用性确实很诱人,我仍然经常使用它们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM