我正在关注一些简单的教程来构建状态菜单应用程序。以下是我的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,如果这有所不同。)
答案 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可以返回零。
编译器只是确保你知道它。