关于Swift中的Optionals

时间:2015-01-23 06:34:24

标签: swift optional

我正在Swift开展一个新项目,并且很难理解选项的特定用途。我已经声明了一个UIRefreshControl属性,可以在类中使用。我宣布它是可选的。

var refreshControl : UIRefreshControl?

在viewDidLoad()中,我首先尝试了以下内容。

override func viewDidLoad()
    {
        super.viewDidLoad()

        self.refreshControl!.addTarget(self, action: Selector("refreshInvoked:"), forControlEvents: UIControlEvents.ValueChanged)
        self.feedsTableView.addSubview(self.refreshControl!)
    }

该应用程序崩溃

self.refreshControl!.addTarget(self, action: Selector("refreshInvoked:"), forControlEvents: UIControlEvents.ValueChanged 
告诉我以下内容。 “致命错误:在打开一个Optional值时意外地发现了nil。”

我意识到我没有实例化UIRefreshControl对象,所以我尝试了以下方法来修复它。

override func viewDidLoad()
    {
        super.viewDidLoad()

        self.refreshControl! = UIRefreshControl()
        self.refreshControl!.addTarget(self, action: Selector("refreshInvoked:"), forControlEvents: UIControlEvents.ValueChanged)
        self.feedsTableView.addSubview(self.refreshControl!)
    }

令我惊讶的是,我收到了与

相同的错误消息
self.refreshControl! = UIRefreshControl()

当我删除!错误消失了,一切正常。

self.refreshControl = UIRefreshControl()

问题

  1. 为什么我们在实例化时不必强制拆开可选项?

  2. 我最好将该属性声明为隐式解包的可选项吗?如果是这样的话?

    var refreshControl:UIRefreshControl!

2 个答案:

答案 0 :(得分:3)

  1. 展开是对可选变量执行的操作,用于提取存储在其中的值,如果不是nil。相反的操作是换行,当值存储在可选变量中时完成 - 不需要执行任何特殊操作符。如果使用强制解包来分配,则实际上是从可选变量中取消一个值,该变量为nil,导致抛出异常

  2. 如果满足以下条件,则声明将属性隐式解包:

    。在容器实例的整个生命周期中,该属性应该是非零的

    B'/ em>的。该属性无法在构造函数

    中初始化

    所有出口都是这种情况,它被定义为隐式展开,因为它们的初始化是在视图控制器生命周期的后期完成的。我通常会避免隐式解包的选项,这是我容忍它们的少数情况之一。

答案 1 :(得分:0)

嗯...

  

<强>? (可选)表示您的变量在时可能包含零值! (unwrapper)表示你的变量在运行时使用(尝试从中获取值)时必须有一个内存(或值)。

主要区别在于,当optional是nil时,可选链接正常失败,而当optional是nil时,强制解包会触发运行时错误。

为了反映可以在nil值上调用可选链接的事实,可选链接调用的结果始终是可选值,即使您要查询的属性,方法或下标返回非可选值。您可以使用此可选返回值来检查可选链接调用是否成功(返回的可选项包含值),或者由于链中的nil值(返回的可选值为nil)而未成功。

具体来说,可选链接调用的结果与预期返回值的类型相同,但包含在可选中。通过可选链接访问时,通常返回Int的属性将返回 Int?

var defaultNil : Int?  // declared variable with default nil value
println(defaultNil) >> nil  

var canBeNil : Int? = 4
println(canBeNil) >> optional(4)

canBeNil = nil
println(canBeNil) >> nil

println(canBeNil!) >> // Here nil optional variable is being unwrapped using ! mark (symbol), that will show runtime error. Because a nil optional is being tried to get value using unwrapper

var canNotBeNil : Int! = 4
print(canNotBeNil) >> 4

var cantBeNil : Int = 4
cantBeNil = nil // can't do this as it's not optional and show a compile time error

Here is basic tutorial in detail, by Apple Developer Committee.