Swift 主从模板应用之谜
Posted
技术标签:
【中文标题】Swift 主从模板应用之谜【英文标题】:Swift Master-Detail Template App Mystery 【发布时间】:2014-06-13 03:54:36 【问题描述】:在 Swift 中运行 Master-Detail App 的略微修改版本时,我收到 Can't unwrap Optional.None
错误。
我所做的只是将第二个 UILabel
添加到 DetailViewController,就在预先存在的 detailDescriptionLabel
下方,当我从MasterViewController 我在设置新标签的语句上崩溃:
secondLabel.text = "This is the Second Label"
我声明这个标签如下:
@IBOutlet var secondLabel : UILabel
真正有趣的是,用于设置detailDescriptionLabel
的预先存在的代码包括新的可选let
语法:
if let label = self.detailDescriptionLabel
label.text = "This is the Detail View"
那么为什么我们需要在这里为detailDescriptionLabel
声明let
?它从未被声明为可选标签,它像任何常规标签 IBOutlet 属性一样被声明,如下所示:
@IBOutlet var detailDescriptionLabel: UILabel
那么为什么它被视为可选?
这是否意味着从现在开始,我添加为 IBOutlet 的任何对象如果我想通过代码进行设置,也必须通过这种let
语句?
编辑:
我在下面的方法中崩溃了,在线anotherLabel.text = "Second Label"
:
func configureView()
// Update the user interface for the detail item.
if let theCar: CarObject = self.detailItem as? CarObject
if let label = self.detailDescriptionLabel
label.text = theCar.make
anotherLabel.text = "Second Label"
但是当我将anotherLabel
与整个if let
业务一起处理时,如下所示,它工作得很好:
if let label2 = self.anotherLabel
label2.text = "Second Label"
【问题讨论】:
【参考方案1】:用@IBOutlet
声明的属性总是隐式展开的可选变量。 Apple's documentation 是这样解释的:
当你在 Swift 中声明一个 outlet 时,编译器会自动 将类型转换为弱隐式解包可选并赋值 它的初始值为零。实际上,编译器替换
@IBOutlet var name: Type
和@IBOutlet weak var name: Type! = nil
。 编译器 将类型转换为隐式展开的可选项,以便您 不需要在初始化程序中分配值。它是隐含的 解包,因为在您的课程从情节提要或 xib 文件,您可以假设插座已连接。奥特莱斯 默认情况下很弱,因为您创建的网点通常很弱 关系。
由于它是隐式展开的,因此您不必每次都必须通过 if let label = something
,只要知道如果您的标签是 nil
并且您尝试使用它,您将最终出现运行时错误。我猜你的第二个标签没有连接到 Interface Builder 中——是这样吗? [OP:不!]
好的,在这种特定情况下发生的情况是,可以从主视图控制器的 prepareForSegue()
调用 configureView()
方法,因为详细视图控制器上的 detailItem
属性具有 didSet
处理程序。发生这种情况时,详细视图控制器尚未加载,因此尚未创建任何标签。由于标签将同时设置,因此您可以将两个初始化都放在该 if 语句下(甚至更清楚一点):
func configureView()
// Update the user interface for the detail item.
if let theCar: CarObject = self.detailItem as? CarObject
if self.detailDescriptionLabel != nil
self.detailDescriptionLabel.text = theCar.make
self.secondLabel.text = "Second Label"
【讨论】:
我的第二个标签绝对已连接到 Interface Builder! :-) 我像往常一样从它直接拖放到代码中,所以它肯定是挂钩的。 (我还仔细检查了 Connections Inspector。)如果我想将文本分配给我的标签,我该如何不通过if let label = something
?
你能多贴一点代码吗?你用什么方法崩溃? (如果这更容易的话,你可以在 gist.github.com 上发布整个内容。)
确定 - 我将代码添加到我原来的问题中 - 见上文。
啊哈!不错的收获! :-) 并且非常有意义。非常有义务 - 标记为正确答案:-)以上是关于Swift 主从模板应用之谜的主要内容,如果未能解决你的问题,请参考以下文章