ios - Swift:比较隐式解包的可选结果为 "unexpectedly found nil while unwrapping an Optional values"

标签 ios swift swift2 ios9

如果得到这个类并且想根据值比较它的实例

class LocationOption: NSObject {
  var name:String!
  var radius:Int!
  var value:String!

  override func isEqual(object: AnyObject?) -> Bool {
    if let otherOption = object as? LocationOption {
        return (self.name == otherOption.name) &&
            (self.radius == otherOption.radius) &&
            (self.value == otherOption.value)
    }
    return false
  }
}

执行此命令时:

var a = LocationOption()
var b = LocationOption()

a.name = "test"
b.name = "test"

if a == b {  // Crashes here!!
  print("a and b are the same");
}

这会因“解包可选值时意外发现 nil”而崩溃?您可以将所有这些复制到 Playground 中进行重现。

这似乎是由于隐式解包可选造成的。如果我将所有字段声明为可选,它将按预期工作。

但就我而言,我希望将这些属性作为隐式解包选项。 isEqual应该怎么写?

===

更新:@matt 是对的,因为我不想更改为“常规”选项,所以我最终得到了这个:

class LocationOption: Equatable {
    var name:String!
    var requireGps:Bool!
    var radius:Int!
    var value:String!
}

func ==(lhs: LocationOption, rhs: LocationOption) -> Bool {
    let ln:String? = lhs.name as String?, rn = rhs.name  as String?
    let lr = lhs.radius as Int?, rr = rhs.radius as Int?
    return ln == rn && lr == rr
}

最佳答案

您无法解开nil。这就是法律。你不能仅仅通过使用隐式解包的Options来绕过这条法则。您隐式解开的选项仍然是选项。因此,当您的测试引用 self.radiusself.value 并且您没有设置它们时,它们为零。所以你试图解开 nil 并且崩溃了。

事实上,如果隐式解包的Options 的使用会让事情变得更糟。当您将它们声明为普通可选值时,它们不会隐式解包,因此它们根本不会解包 - 将普通可选值与 == 运算符进行比较是安全的,因为编译器会插入 nil 为您测试。因此,法律永远不会被违反。但是,通过创建这些隐式展开的可选值,您已经抛弃了这种安全性。 这就是感叹号的意思;这意味着你可能会崩溃。如果你不希望这种情况发生,那么:

  • 不要这样做。或者:

  • 您自己插入一个对 nil 的显式测试。

关于ios - Swift:比较隐式解包的可选结果为 "unexpectedly found nil while unwrapping an Optional values",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32701824/

相关文章:

ios - 我怎么能从 js 世界传递 swift 自定义组件的属性

ios - 一种UIView动画取消了iOS中的另一种动画

ios - 状态栏样式不会因单个 View 而改变 - Swift 2/iOS9

xcode - 在一个 NSURLSession.sharedSession 上运行 2 个任务

ios - SWIFT 2 - 按日期排序多维数组

ios - IBAction 连接到 IF 语句

iphone - 在 UIPopover 中显示 ABPeoplePickerNavigationController

ios - 使用 NSTemporaryDirectory 写入视频文件

ios - 如何在swift中制作线程安全的代码块

swift - 如何从 PHAsset 获取视频的缩略图?