Swift Master-Detail模板App神秘

时间:2014-06-13 03:54:36

标签: ios swift iboutlet optional

我在Swift中运行稍微修改过的Master-Detail App版本时出现Can't unwrap Optional.None错误。

我所做的就是在 DetailViewController 中添加第二个UILabel,在预先存在的detailDescriptionLabel下面,当我导航到 DetailViewController 来自 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"
        }

那么为什么let需要detailDescriptionLabel声明?它从未被声明为可选标签,它被声明为任何常规的标签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 个答案:

答案 0 :(得分:4)

使用@IBOutlet声明的属性始终是隐式解包的可选变量。 Apple's documentation以这种方式解释:

  

当您在Swift中声明一个插座时,编译器会自动生成   将类型转换为弱隐式解包的可选和分配   它的初始值为零。实际上,编译器会替换   @IBOutlet var name: Type @IBOutlet weak var name: Type! = nil if let label = something。    编译器   将类型转换为隐式展开的可选项以便您   不需要在初始化程序中分配值。这是隐含的   解开因为你的课程从故事板或故事板初始化后   xib文件,您可以假设插座已连接。奥特莱斯   默认情况下很弱,因为你创建的网点通常很弱   关系。

由于它是隐式展开的,因此您不必 每次都要通过nil,只要知道您的标签是configureView()并且你尝试使用它,你最终会遇到运行时错误。我猜你的第二个标签并没有在Interface Builder中连接 - 是这样的吗? [OP:没有!]


好的,在这种特定情况下发生的事情是prepareForSegue()方法可以从主视图控制器detailItem调用,因为didSet属性在详细视图控制器上有一个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" } } } 处理程序。发生这种情况时,尚未加载详细视图控制器,因此未创建任何标签。由于标签将同时设置,您可以将两个初始化放在if if语句下(并使其更清晰,甚至):

{{1}}