swift – 如何正确检查非可选返回值是否有效?

我试图检查一个返回值时遇到一个奇怪的情况,我想知道如何在Swift意义上“正确地”这样做。

我有一个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
method or property never returns a nil object reference. To make
objects in this special scenario more convenient to work with,Swift
imports object types as implicitly unwrapped optionals. Implicitly
unwrapped optional types include all of the safety features of
optional types. In addition,you can access the value directly without
checking for nil 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
}

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...