我刚刚发现Set
类型的MKAnnotation
无法正常工作。
class MyAnnotation: MKPointAnnotation {
let id: String
init(_ id: String) {
self.id = id
}
override var hash: Int {
return id.hash
}
static func ==(lhs: MyAnnotation, rhs: MyAnnotation) -> Bool {
return lhs.hashValue == rhs.hashValue
}
}
let m1 = MyAnnotation("1")
let m2 = MyAnnotation("2")
let n1 = MyAnnotation("1")
let n2 = MyAnnotation("2")
m1.hashValue //918
n1.hashValue //918
m2.hashValue //921
n2.hashValue //921
if m1 == n1 && m2 == n2 {
print(true)
}
// prints true
let s1 = Set(arrayLiteral: m1, m2)
let s2 = Set(arrayLiteral: n1, n2)
let i = s1.intersection(s2)
// empty
即使散列相同,m和n的交集也是空的。请与下面的示例进行比较:
class MyAnnotation: Hashable, Equatable {
let id: String
init(_ id: String) {
self.id = id
}
var hashValue: Int {
return id.hash
}
static func ==(lhs: MyAnnotation, rhs: MyAnnotation) -> Bool {
return lhs.hashValue == rhs.hashValue
}
}
let m1 = MyAnnotation("1")
let m2 = MyAnnotation("2")
let n1 = MyAnnotation("1")
let n2 = MyAnnotation("2")
m1.hashValue //918
n1.hashValue //918
m2.hashValue //921
n2.hashValue //921
if m1 == n1 && m2 == n2 {
print(true)
}
// prints true
let s1 = Set(arrayLiteral: m1, m2)
let s2 = Set(arrayLiteral: n1, n2)
let i = s1.intersection(s2)
// {{id "1"}, {id "2"}}
m和n的交集符合预期。
这很奇怪吗?也许中间有些东西我不知道也不了解。
Xcode 10.1
答案 0 :(得分:0)
在第一个代码中,您没有使用Equatable协议,但是在第二个代码中,您使用了Equatable协议,因此它可以正常工作。
使用quaquatable协议进行比较。您可以参考下面的链接以获取更多信息:
https://useyourloaf.com/blog/swift-equatable-and-comparable/
答案 1 :(得分:0)
解决方案是覆盖isEqual(_ object: Any?) -> Bool
。
由于MKAnnotation
源自NSObject
,因此我们需要覆盖NS的方法。如果我们深入研究实现(^
+ ⌘
),我们会发现:
NSObject
的子类可以通过覆盖isEqual(_:)
来定制Equatable一致性。如果两个对象相等,则它们必须具有相同的哈希值,因此,如果覆盖isEqual(_:)
,请确保还覆盖hash
属性。