如果得到这个类,并希望根据值
比较它的实例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
}
答案 0 :(得分:4)
您无法解开nil
。这就是法律。你不能仅仅通过使用隐式解包的Optionals来解决这个问题。您隐式解包的选项仍然是Optionals。因此,当您的测试引用self.radius
和self.value
并且您没有设置它们时,它们就是零。所以你试图解开nil
然后崩溃。
事实上,如果隐式展开的Optionals你的使用会让事情变得更糟。当您将它们声明为正常的Optionals时,它们不会被隐式解包,因此它们根本不会被打开 - 将正常的Optionals与==
运算符进行比较是安全的,因为编译器会为您插入nil
测试。因此,法律从未被违反。但是你通过制作这些隐含的未包装的Optionals而抛弃了这种安全性。 这就是感叹号的含义;这意味着你可以崩溃。如果你不希望发生这种情况,那么:
不要这样做。或者:
自己插入nil
的明确测试。