var label: UILabel! 有什么区别?和 var label = UILabel( )?

What's the difference between var label: UILabel! and var label = UILabel( )?

我在写 Swift 时注意到,如果我在 ViewController 中将标签声明为 var label: UILabel!var label = UILabel(),然后在viewDidLoad 方法,它们在功能上似乎都是相同的。那么这两者有什么区别呢?

相关说明,当我声明 var label: UILabel! 时,我必须写 label = UILabel(frame:CGRectMake(...)),但如果我使用 var label = UILabel(),我必须写 label.frame = CGRectMake(...)。这是因为 var label = UILabel() 既声明又实例化了 class 对象,而 var label: UILabel! 只是声明了一个类型的变量吗?我对这里实际发生的事情感到困惑。

提前致谢!

var label: UILabel!

声明您有一个可能为空的 UILabel 变量(可选),但您可以假装它不会访问它 - 通常这意味着它将是一个 IBOutlet,由界面故事板设置在您尝试使用标签之前加载。

var label = UILabel()

声明您有一个标签,该标签将始终包含一个标签,并且永远不会为零。它也在创建 class 实例时创建 UILabel 的实例,即使您说您为 viewDidLoad()

中的变量分配了不同的标签

访问权限没有区别,但这确实意味着无论您何时使用该变量,它都将保存一个真实值而不是 nil。

它们都是UILabel.

类型的变量

我不确定为什么您不能使用 CGRect 构造函数将变量设置为新的 UILabel,这应该是可能的。也许你曾经说过 let label = UILabel(),这意味着它是一个不能保存新值的固定变量 - 所以你所能做的就是改变已经存在的变量的框架。

像你正在做的事情的最佳方法是将变量声明为可选:

 var label : UILabel?

这使它成为一个真正的可选,并确保您不会意外编写错误地访问变量的代码,如果它从未被设置,或者在您分配 "real" 之前为您的第一个标签设置一个值viewDidLoad 方法中的 UILabel。访问有点不同,但并不难 - 要设置文本,您只需使用“?”如果实例已设置,可选择调用 属性 的语法:

label?.text = "fred"

你是对的。 UILabel() 调用 UILabel 无参数构造函数并将该对象引用分配给 label 变量。所以这是一个声明和一个初始化。

在构造函数的情况下,label 不是可选的,被推断为直接的 UILabel 类型,但在声明的情况下 label 一个Optional类型。这 !只是意味着它是一个可选的强制展开,所以当你将它用作一个值时,你不必输入 !;但是,如果您将其声明为强制展开并在其值为 nil 时使用它,您的程序将崩溃。

另请注意,您不能申报:

var label: UILabel

作为 class 成员 除非您在所有构造函数中初始化它,在(可能是隐式的)调用 super.init() 之前,因为它会抱怨没有初始值,因此它可能被引用时没有已知值——Swift 编译器会阻止这种情况。