如果有此类,并且想根据该值比较它的实例
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.radius
和self.value
而您尚未设置它们时,它们为零。因此,您尝试解开nil
并崩溃。
实际上,如果隐式解开Optionals,则使情况变得更糟。当您将它们声明为普通的Optional时,它们不会被隐式解包,因此也根本不会被解包-将常规Optionals与==
运算符进行比较是安全的,因为编译器会为您插入nil
测试。因此,从未违反该法律。但是您通过使这些隐式展开的Optionals放弃了这种安全性。这就是感叹号的含义;这意味着您可能会崩溃。如果您不希望发生这种情况,请执行以下操作:
nil
插入一个显式测试。