关于 Swift 中的可选项

About Optionals in Swift

我正在 Swift 从事一个新项目,但我很难理解可选值的特定用途。我已经声明了一个 UIRefreshControl 属性 用于 class。我声明它是可选的。

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 

告诉我以下内容。 "fatal error: unexpectedly found nil while unwrapping an Optional value."

我意识到我没有实例化 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!

  1. 解包是对可选变量执行的操作,以提取存储在其中的值(如果不是 nil)。相反的动作是包装,当一个值存储在一个可选变量中时完成——这不需要执行任何特殊的运算符。如果使用强制解包赋值,实际上是从一个可选变量中解包一个值,这个值是nil,导致抛出异常

  2. 如果满足这些条件,将 属性 声明为隐式展开是有意义的:

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

    b。 属性 无法在构造函数中初始化

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

嗯...

? (Optional) indicates your variable may contain a nil value while ! (unwrapper) indicates your variable must have a memory (or value) when it is used (tried to get a value from it) at runtime.

主要区别在于当可选值为 nil 时,可选链接会优雅地失败,而当可选值为 nil 时,强制解包会触发运行时错误。

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

具体来说,可选链调用的结果与预期的 return 值具有相同的类型,但包含在可选中。通常 return 是 Int 的 属性 将 return 是 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.