我有一个NSStatusItem(命名项),我正在尝试分配NSStatusItem一个NSImage。当我做NSImage时,因为我传递一个字符串值为图像名称,我想确保NSImage实际上是有效的(如果我输入图像名称字符串怎么办?)。
我尝试的第一件事是这样的:
if let image: NSImage? = NSImage(named: "CorrectIconName") { item.image = image }
但是这会给出错误“条件绑定中的绑定值必须为可选类型”。我以为说形象:NSImage?说明这是可选的,但我猜不是。
我改为:
let image: NSImage? = NSImage(named: "CorrectIconName") if image { item.image = image }
哪个工作完全正常但是我不明白为什么这样工作,而第一个例子没有。看起来似乎是完全一样的事情。而且由于第一个没有编译,我以为我会尝试一些其他的路由…
由于NSImage(命名:)确实返回NSImage而不是NSImage?,我以为我会看到发生了什么,如果我将构造函数的返回值直接分配给item:
item.image = NSImage(named: "CorrectIconName")
哪个工作,但不允许我想做错误检查。如果字符串错误,NSStatusItem对于图像将不会为零,这导致我有一个不可见状态栏项。
接下来,我试过这个:
let image: NSImage = NSImage(named: "CorrectIconName") if image { item.image = image }
但是这会给出错误“Type”NSImage“不会确认协议”LogicValue“”,我猜这意味着你不能使用if语句来检查它是否为零。
但是,您可以通过执行以下操作来检查是否为零:
let image: NSImage = NSImage(named: "CorrectIconName") if image != nil { item.image = image }
所以,这里是一个问题:如果不是可选,那么应该如何检查返回值?
在Apple关于使用Objective-C对象的文档中,它表示从Objective-C API导入的所有对象实际上都是隐式展开的可选项(就像我们手动声明的一样!):
In some cases,you might be absolutely certain that an Objective-C@H_301_41@ method or property never returns a
nil
object reference. To make@H_301_41@ objects in this special scenario more convenient to work with,Swift@H_301_41@ imports object types as implicitly unwrapped optionals. Implicitly@H_301_41@ unwrapped optional types include all of the safety features of@H_301_41@ optional types. In addition,you can access the value directly without@H_301_41@ checking fornil
or unwrapping it yourself. [07000]
不幸的是,编译器/语法检查器不会这样对待它们。因此,正确的检查方式是将图像声明为NSImage初始化程序实际返回的类型,即隐式解包的可选NSImage:
let image: NSImage! = NSImage(named: "CorrectIconName") if image { // do something }
替代方法(通过@vacawama):
if let image = NSImage(named: "CorrectIconName") as NSImage! { // do something }