Swift中的NSObject子类:hash vs hashValue,isEqual vs ==
在Swift中对NSObject进行子类化时,应该覆盖哈希还是实现Hashable?另外,你应该覆盖isEqual:还是实现==?
NSObject已经符合Hashable协议:
extension NSObject : Equatable,Hashable { /// The hash value. /// /// **Axiom:** `x == y` implies `x.hashValue == y.hashValue` /// /// - Note: the hash value is not guaranteed to be stable across /// different invocations of the same program. Do not persist the /// hash value across program runs. public var hashValue: Int { get } } public func ==(lhs: NSObject,rhs: NSObject) -> Bool 我找不到官方参考,但似乎是hashValue 对于NSObject子类,似乎是正确的方式 覆盖hashValue和== class ClassA : NSObject { let value : Int init(value : Int) { self.value = value super.init() } override var hashValue : Int { return value } } func ==(lhs: ClassA,rhs: ClassA) -> Bool { return lhs.value == rhs.value } 现在创建被考虑的类的两个不同实例 let a1 = ClassA(value: 13) let a2 = ClassA(value: 13) let nsSetA = NSSet(objects: a1,a2) let swSetA = Set([a1,a2]) print(nsSetA.count) // 2 print(swSetA.count) // 2 您可以看到,NSSet和Set都将对象视为不同的对象。 let nsArrayA = NSArray(object: a1) let swArrayA = [a1] print(nsArrayA.indexOfObject(a2)) // 9223372036854775807 == NSNotFound print(swArrayA.indexOf(a2)) // nil 设置断点或添加调试输出显示被覆盖 2.覆盖哈希和isEqual: class ClassB : NSObject { let value : Int init(value : Int) { self.value = value super.init() } override var hash : Int { return value } override func isEqual(object: AnyObject?) -> Bool { if let other = object as? ClassB { return self.value == other.value } else { return false } } } 对于Swift 3,isEqual的定义:更改为 override func isEqual(_ object: Any?) -> Bool { ... } 现在所有的结果都如预期的那样 let b1 = ClassB(value: 13) let b2 = ClassB(value: 13) let nsSetB = NSSet(objects: b1,b2) let swSetB = Set([b1,b2]) print(swSetB.count) // 1 print(nsSetB.count) // 1 let nsArrayB = NSArray(object: b1) let swArrayB = [b1] print(nsArrayB.indexOfObject(b2)) // 0 print(swArrayB.indexOf(b2)) // Optional(0) 更新:现在记录的行为
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |