为什么 out 不能在 initWithCoder 中初始化?



我们都知道,一旦我们在 View 或其 ViewController 中放置一个出口,它就会被标记为已解包,我们都知道 Swift 希望在初始化阶段初始化所有属性,这是我们给第一次问我们为什么出口总是与感叹号在一起的人的句子。

今天我试图理解为什么来自 XIB 的对象不能在initWithCoder:方法中初始化。

据我所知,一个 XIB 文件只包含有关使用 XML 文件结构在 XIB 内部绘制的对象的所有信息。 因此,我们在XIB文件中看到的内容将被存档并存储到文件中。

当我们调用UINibloadNibNamed:owner:options:类方法时,它将解压缩之前创建的对象,查找所有属性,设置它们并将消息awakeFromNib发送到对象......

但是由于感叹号说"在初始化阶段我无法初始化你",我上面所说的应该是不正确的。但是为什么? 有人可以告诉我为什么 Nib 不能初始化并且应该标记为可选吗?

在这里,我有一些来自Apple的文档,这些文档对我没有帮助 https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/CocoaNibs.html

您的@IBOutlet属性由您的UIViewController子类引入。

说"Swift 想要初始化初始化阶段的所有属性"有点过于简单化了。

Swift 初始化规则规定,在调用超类初始化器之前,必须初始化子类引入的所有属性,并且 Swift 编译器必须能够"看到"此初始化;必须有一个显式赋值。 这是"安全检查1":-

安全检查 1

指定的初始值设定项必须确保在将其类引入的所有属性委托给超类初始值设定项之前都已初始化。

在几乎所有使用 XIB 或情节提要场景的情况下,您都不会覆盖init(coder:),因此编译器可以确定您尚未为这些属性显式分配值

如果您确实覆盖了初始化器并分配了值(或者即使您在声明属性时只是分配了默认值(,那么您可以使它们成为普通属性,而不是隐式解包的可选,但这有点毫无意义,因为加载 XIB 时您几乎会立即覆盖这些值。

隐式解包的可选不会说"在初始化阶段,我无法初始化你";它更像是"我知道看起来这没有被初始化,但在运行时它会被初始化。相信我"(严格来说,它只是声明一个 optional,它被允许nil,所以编译器不会抱怨它没有初始化,而是在引用属性时隐式强制解包 - 因此得名"隐式解包可选"(。

这适用于@IBOutlet秒,因为加载过程使用键值编码在运行时分配值。

这就是为什么,如果您删除了@IBOutlet但忘记更新 XIB/情节提要,您会收到一个运行时异常,指出您的类"不符合 xxx 的键/值"。

以这种方式使用隐式解包的可选包通常被认为是可以接受的,因为您将很快发现在测试期间是否有连接问题(因为您的应用程序会崩溃并显示"意外的 nil"(,并且它节省了大量条件解包。

相关内容

  • 没有找到相关文章

最新更新