我想了解为什么

var tmp: Any = NSImage(byReferencingFile: somePath)
var img: NSImage = tmp as NSImage


将无法正常工作并导致错误,但是

var tmp: Any = NSImage(byReferencingFile: somePath) as Any!
var img: NSImage = tmp as NSImage


会做这份工作吗?有什么不同?

最佳答案

ew,这设法将许多不同的问题打包成少量的代码:-)这种解释很长,因此您可能会发现您知道它的第一部分,但也可能从头开始。

NSImage(byReferencingFile)是所谓的“失败的初始值设定项”,也就是返回NSImage?的初始值设定项–一个可能包含或可能不包含NSImage对象的可选值。

原因是,从文件创建NSImage可能会失败(假设找不到该文件)。因此,它返回一个必须检查并解开的可选内容:

if let img = NSImage(byReferencingFile: somePath) {
    // img will be a valid NSImage
}
else {
    // img was not valid, handle error here if you want
}


现在,如果您尝试将NSImage?(由失败的初始化程序返回)分配给非可选的NSImage,则会收到错误消息,因为您无法执行此操作–您需要执行以下操作:如上所示:

// error: value of optional type 'NSImage?' not unwrapped; did you mean to use '!' or '?'?
let img: NSImage = NSImage(byReferencingFile: somePath)


如上面的错误消息所述,一种解决此问题的方法不是用if … let展开图像,而是“强制展开”可选内容,如下所示:

let img: NSImage = NSImage(byReferencingFile: somePath)!
                             // note exclamation mark -^


!的意思是:不用费心检查nil,只需假设结果有效并解开即可。有时这是一个好主意,但通常是一个非常不好的主意。如果您曾经强制拆开nil值,则程序将突然退出并出现错误。因此,除非您100%确信不可能将值设为nil(这不是很常见),否则应避免这样做。

好吧,Any!如何影响所有这一切?

后面带有!的类型是“隐式展开的可选”。这些是可选的,但您不必手动强行打开。您可以像访问常规值一样访问它们-但是,如果再次访问nil值,则应用程序将退出。

因此,您可以编写以下代码:

let img: NSImage! = NSImage(byReferencingFile: somePath)
// or, this is basically the same thing:
let img = NSImage(byReferencingFile: somePath) as NSImage!


现在,您可以像使用img一样使用它了。但是,如果像以前一样为零,它将崩溃。区别在于,使用img时,它将崩溃,而不是将其分配给img时,崩溃。

最后,Any是一种可以容纳任何类型的类型,但在不返回真实类型的情况下几乎没有用。通常应使用as?进行此操作。 as?检查Any是否包含该类型,并返回包含该值的可选值,或者返回nil(如果它包含其他类型)。

如果将可选内容放入Any,然后尝试将其提取为非可选内容,它将失败并返回nil,因为您输入的类型与您尝试获取的类型不同。

相反,如果您使用as而不带问号,则会强制提取而不将其包装在可选文件中,并且您猜想它会在运行时爆炸,如果出错的话。实际上,这看起来很危险,但看起来很天真,因此在新的1.2 beta版本的Swift中,它已被替换为as!,以适应其强制展开的特性。在第一个示例中,您放入了NSImage?,您要提取一个非可选的NSImage,并使用as,因此您会获得运行时断言。

无论如何,Any!会将以上所有功能组合到一个令人愉悦的弹簧式死亡陷阱中。它会很高兴地采用一个可选类型,然后允许您未经检查就将其内容提取为非可选类型。这就是代码中发生的事情–您将可选内容放入Any!,然后将其提取为非可选内容。几乎可以肯定这是一个坏主意,因为如果找不到您的图像文件,它将崩溃。因此,最好在此答案的开头使用代码从图像中提取值。

关于swift - 将NSImage类型转换为Any并将其向下转换回NSImage,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28918937/

10-12 05:51