本文介绍了NSObject子类中的Swift:hash vs hashValue,isEqual vs ==的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
当子类化NSObject在Swift,应该覆盖哈希还是实现Hashable?此外,你应该覆写isEqual:或implement ==?
解决方案
NSObject
已经符合 Hashable
协议:
Hashable {
///哈希值。
///
/// ** Axiom:**`x == y`意味着`x.hashValue == y.hashValue`
///
// / - 注意:哈希值不能保证在同一程序的
///不同调用之间是稳定的。不要在程序运行时保持
///哈希值。
public var hashValue:Int {get}
}
public func ==(lhs:NSObject,rhs:NSObject) - > Bool
我找不到官方参考,但似乎 hashValue
从 NSObjectProtocol
和调用
调用 hash
==
isEqual:
方法(来自同一协议)。 查看
结尾的更新!
NSObject
子类,正确的方法似乎是
重写 hash
和 isEqual:
,这里是一个实验其中
证明:
1。覆盖 hashValue
和 ==
code> class ClassA:NSObject {
let value:Int
init(value:Int){
self.value = value
super.init )
}
override var hashValue:Int {
返回值
}
}
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 ,a2])
print(nsSetA.count)// 2
print(swSetA.count)// 2
如您所见, NSSet
和设置
对象不同。
这不是所需的结果。数组也有意想不到的结果:
let nsArrayA = NSArray(object:a1)
let swArrayA = [a1]
print(nsArrayA.indexOfObject(a2))// 9223372036854775807 == NSNotFound
print(swArrayA.indexOf(a2))// nil
设置断点或添加调试输出显示重写的
==
称为。我不知道这是一个错误还是
的预期行为。
2。覆盖 hash
和 isEqual:
code> class ClassB:NSObject {
let value:Int
init(value:Int){
self.value = value
super.init )
}
override var hash:Int {
返回值
}
override func isEqual(object:AnyObject?) - > ; Bool {
如果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)
让nsSetB = NSSet (对象:b1,b2)
让swSetB = Set([b1,b2])
打印(swSetB.count)// 1
打印(nsSetB.count) / 1
let nsArrayB = NSArray(object:b1)
let swArrayB = [b1]
print(nsArrayB.indexOfObject(b2))// 0
print(swArrayB.indexOf(b2))//可选(0)
更新:现在,行为记录在
在使用Swift与Cocoa和Objective-C引用:
这篇关于NSObject子类中的Swift:hash vs hashValue,isEqual vs ==的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!