如果有此类,并且想根据该值比较它的实例

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中进行复制。

这似乎是由于Implicitly Unwrapped Optionals造成的。如果我将所有字段都声明为Optionals,它将按预期工作。

但就我而言,我想将这些属性作为Implicitly Unwrapped Optionals。我应该如何写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。那是法律。您不能仅通过使用隐式解包的Optional来绕开该法则。您隐式解包的可选参数仍然是可选参数。因此,当您的测试涉及self.radiusself.value而您尚未设置它们时,它们为零。因此,您尝试解开nil并崩溃。

实际上,如果隐式解开Optionals,则使情况变得更糟。当您将它们声明为普通的Optional时,它们不会被隐式解包,因此也根本不会被解包-将常规Optionals与==运算符进行比较是安全的,因为编译器会为您插入nil测试。因此,从未违反该法律。但是您通过使这些隐式展开的Optionals放弃了这种安全性。这就是感叹号的含义;这意味着您可能会崩溃。如果您不希望发生这种情况,请执行以下操作:

  • 不要这样做。或者:
  • 自己为nil插入一个显式测试。
  • 10-08 05:25