I have created a class that adopt Hashable
protocol.
So I created some instances of this class with different properties and added them to the Set.
Then I change a property of an object.
After this change the Set sometimes fail .contains
(and also .remove
).
In the debugger inspector I see that the object has the same memory address of the element inside the Set. So why fail at random?
Note that I can always found the index of the element inside the set.
I tested with playground (on xcode10) several times and on every execution the results change.
class Test: Hashable {
// MARK: Equatable protocol
static func == (lhs: Test, rhs: Test) -> Bool {
return lhs === rhs || lhs.hashValue == rhs.hashValue
}
var s: String
func hash(into hasher: inout Hasher) {
hasher.combine(s.hashValue)
}
init(s: String) {
self.s = s
}
}
func test(s: Set<Test>, u: Test) -> Bool {
if s.contains(u) {
print("OK")
return true
} else {
print("FAIL") // SOMETIMES FAIL
if !s.contains(u) {
if let _ = s.firstIndex(where: { $0 == u }) {
print("- OK index") // ALWAYS OK
return true
} else {
print("- FAIL index") // NEVER FAIL
return false
}
} else {
return true
}
}
}
var s: Set<Test> = []
let u1 = Test(s: "a")
s.insert(u1)
let u2 = Test(s: "b")
s.insert(u2)
test(s: s, u: u2)
u2.s = "c"
test(s: s, u: u2)
u2.s = "d"
test(s: s, u: u2)
u2.s = "b"
test(s: s, u: u2)