【问题标题】:How can I avoid the Optional.None error in this scenario?在这种情况下如何避免 Optional.None 错误?
【发布时间】:2014-08-24 00:08:55
【问题描述】:
var image = self.imageData[index] as NSString     
        if let derp = image as NSString? {
            println(" \(image)")
        } else {
            println("is nil")
        }

        dataViewController.dataImage.image = UIImage(named: image) as UIImage

最后一行:

dataViewController.dataImage.image = UIImage(named: image) as UIImage

给了我“无法解开 Optional.None”,尽管图像对象成功通过了可选绑定测试,如此处所示 https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-XID_428 。图像字符串确实打印在 Xcode 的底部。

【问题讨论】:

标签: ios uiimage swift


【解决方案1】:

您可能会收到该错误,因为具有该名称的图像不存在。但是,您的可选绑定也存在一些问题。

  1. 可选绑定不同于强制转换。您不提供新类型。此外,即使强制转换是执行此操作的方法,您也是在强制转换为可选项,这并不能证明 image 不是 nil。

  2. 您已经在第一行使用as NSString 向编译器断言图像不为零。如果此转换在运行时不成功,您的整个应用将崩溃。

  3. 绑定可选项后,应使用局部变量,以后不要使用可选项

这意味着您的代码应如下所示:

var possibleImageName = self.imageData[index] as? NSString     
if let imageName = possibleImageName {
    var possibleImage : UIImage? = UIImage(named: imageName)
    if let image = possibleImage {
        dataViewController.dataImage.image = image
    }
} else {
    println("is nil")
}

在了解了可选绑定过程,以及与强制转换的区别后,可以将代码缩短为:

if let imageName = self.imageData[index] as? NSString {
    if let image = UIImage(named: imageName) as UIImage? {
        dataViewController.dataImage.image = image
    }
} else {
    println("is nil")
}

注意:从初始化程序中检查 nil 很奇怪。您必须将其转换为可选类型,以便您可以实际测试它,因为来自 Objective-C 的初始化程序实际上返回 Implicitly Unwrapped Optionals

【讨论】:

  • 我收到一个错误:“条件中的绑定值必须是可选类型”,对于最后一个示例。
  • @user3784622 是的,我刚刚测试过。我忘记了您不能将初始化程序视为可选。我更新了我的答案。
  • 天哪,我发现这个可选的东西令人困惑!你是如何花时间去理解它们的? swift手册是目前最好的选择吗?谢谢。
  • 当从UIImage(named: imageName) 返回的UIImage 解包导致的错误时,您的代码将不起作用。检查this answer
  • @user3784622 对我来说是阅读 swift 手册和潜伏在堆栈溢出中的结合;)
【解决方案2】:

UIImage(named:) 可能会返回nil,以防找不到具有给定名称的图像。您需要检查它是否为零。

var img : UIImage? = UIImage(named: image)
if img != nil {
    dataViewController.dataImage.image = img!
}

if let img = UIImage(named: image) as UIImage! {
    dataViewController.dataImage.image = img
}

【讨论】:

  • 为什么将img 设为隐式展开的可选?特别是在第二种情况下,您可以将其设为非可选,因为您使用的是可选绑定。
  • @drewag 为什么不呢?对于第二种情况,我不能 100% 确定 drop optional 它会起作用,我现在无法对其进行测试。
  • 在第一种情况下,如果某些东西真的可以为 nil,那么您应该始终使用实际的可选项,然后编译器会强制您打开它。在第二种情况下,隐式展开的可选项实际上什么都不做。最好的情况,它只是更冗长。尽管我自己对此进行了测试,但您不能将初始化程序视为可选的,因此这两个版本都不会编译。
  • 第一种情况你是对的。但对于第二种情况,你错了。构造函数默认返回非可选值是一种解决方法
  • 是的,你是对的,我没有意识到有一种方法可以测试 nil 的初始化程序,谢谢。
猜你喜欢
  • 2013-04-17
  • 1970-01-01
  • 1970-01-01
  • 2015-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-21
  • 1970-01-01
相关资源
最近更新 更多