为什么斯威夫特坚持认为这是一个可选的?

时间:2015-09-02 06:00:34

标签: swift

警告:我已经在Swift中编码了大约2天了!

我正在关注一些简单的教程来构建状态菜单应用程序。以下是我的AppDelegate.swift类的缩减:

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    @IBOutlet weak var window: NSWindow!
    @IBOutlet weak var statusMenu: NSMenu!

    let statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(-2)

    func applicationDidFinishLaunching(aNotification: NSNotification) {
        let icon = NSImage(named: "StatusBarImage")
        icon?.setTemplate(true)
    }
}

我的问题是,为什么Xcode坚持认为我的icon常量是可选的(我也强迫它被解包)。该教程没有显示需要?,但如果我将其删除,Xcode会向我显示以下错误:

Value of optional type 'NSImage' not unwrapped; did you mean to use '!' or '?'?

(我正在使用Xcode 6.4,如果这有所不同。)

4 个答案:

答案 0 :(得分:2)

来自Document

<强>声明:

init?(named name: String) -> NSImage

默认情况下,它的初始化程序是可选的。

返回值

  

与指定名称关联的NSImage对象,如果不是,则为nil   发现了这样的形象。

<强>讨论

  

NSImage类可以缓存对返回的图像对象的引用   在某些情况下的表现。但是,该类保持缓存   仅在对象存在时才对象。如果所有强引用的话   随后移除图像,可以安静地移除物体   缓存。因此,如果您打算保留返回的图像对象,那么   必须保持对它的强烈引用,就像你对任何Cocoa一样   宾语。您可以通过显式清除缓存中的图像对象   调用对象的setName:方法并为图像指定nil   名。

这就是为什么它会问你did you mean to use '!' or '?'

因此,如果您使用!表示您正在解包可选值,并且使用?编译器会将其视为可选值。

答案 1 :(得分:1)

因为名为 StatusBarImage 的图片可能不在资产中,并且会导致错误的访问异常。

答案 2 :(得分:1)

实际上Xcode没有强制执行任何操作:如果您查看NSImage文档,您将看到NSImage初始化程序是可用的初始化程序

就像@FruitAddict所说,当无法创建对象时,这些初始化器的重点是优雅地失败(通过返回带有nil值的可选项)。 Check Apple Developer Blog

答案 3 :(得分:0)

加入!或这个 ?您明确知道imageNamed可以返回零。

编译器只是确保你知道它。