Создание подклассов MKAnnotation причина Набор коллекций не работает - PullRequest
0 голосов
/ 12 ноября 2018

Я только что обнаружил, что 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

Ответы [ 2 ]

0 голосов
/ 06 декабря 2018

Решение состоит в том, чтобы переопределить isEqual(_ object: Any?) -> Bool.

Поскольку MKAnnotation является производным от NSObject, нам нужно переопределить метод NS.Если мы углубимся в реализацию (^ + ), то обнаружим:

Подклассы NSObject могут настроить соответствие Equatable путем переопределения isEqual(_:).Если два объекта равны, они должны иметь одинаковое хеш-значение, поэтому, если вы переопределяете isEqual(_:), убедитесь, что вы также переопределяете свойство hash.

0 голосов
/ 12 ноября 2018

В первом коде вы не использовали Equatable протокол, но во втором коде вы использовали Equatable протокол, чтобы он работал.

Equatable протокол используется для сравнения.Вы можете обратиться по ссылке ниже для получения дополнительной информации:

https://useyourloaf.com/blog/swift-equatable-and-comparable/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...