RealmSwift - Как переопределить хэш-функцию при переносе существующего класса в Realm - PullRequest
0 голосов
/ 09 января 2019

У меня есть существующий класс Movie, который я хочу сохранить с использованием RealmSwift Framework. Ранее я соответствовал Movie протоколу Hashable (для выполнения Set() операций над массивами фильмов), но это становится избыточным из-за требования Realm о соответствии его протоколу Object.

Тем не менее, теперь я получаю сообщение об ошибке (мое) объявление функции hash(into hasher: _) (при необходимости Hashable):

Overriding declarations in extensions is not supported
Overriding non-open instance method outside of its defining module
1. Overridden declaration is here (ObjectiveC.NSObject)

Screenshot of the error messages from declaring func hash(...), as previously required to conform to Hashable


Я проверил много отчетов о проблемах в репозитории Realm git, но безуспешно (некоторые из них были неправильно помечены как закрытые, я полагаю):

Я пробовал с объявленным primaryKey и без него, а также ввод фиктивного начального (гарантированного уникального) идентификатора через dynamic var id = UUID().uuidString - хотя следует отметить, что Movie() равно НИКОГДА вызывается - я всегда использую (теперь удобно, с этим рефактором Realm) convenience init(title: String, id: String, cast: String ) инициализатор.

Некоторые предложения включают переопределение переменной hash или hashValue, но последняя была сделана избыточной первой (и первая все еще не работает для меня - в этом примере я просто использую * Параметр 1056 * для Movie hash/hashValue:

override var hash: Int {
  return id.hashValue
}

override var hashValue: Int {
  return id.hashValue
}

Мой Movie код выглядит следующим образом (с фатальной ошибкой на func hash(into hasher: inout Hasher) {, как показано на скриншоте выше):

import Foundation
import UIKit
import EventKit
import RealmSwift

@objcMembers class Movie: Object {
 dynamic var title: String = ""
 dynamic var id: String = ""
 dynamic var cast: String  = ""

 convenience init(title: String, id: String, cast: String ) {
    self.init()
    self.title = title
    self.id = id
    self.cast = cast
 }

 override static func primaryKey() -> String? {
    return "id"
 }

 func hash(into hasher: inout Hasher) {
    hasher.combine(title)
    hasher.combine(id)
    hasher.combine(cast)
 }
}

Пример арифметики Set(), которую я хочу выполнить для массивов фильмов, [Movie]. В этом примере я проверяю, является ли subSetOfMovies подмножеством allMovies, if-not , затем добавьте его в список allMovies:

 if !Set<Movie>(subSetOfMovies).isSubset(of: Set(allMovies)) {
   allMovies.append(contentsOf: subSetOfMovies)
 } else {
   print("subSetOfMovies is a subset of allMovies, thus it is not added.")
 }

Примечание: я хочу использовать арифметику Set, потому что это очень быстро. Для длинных списков фильмов я не хочу проверять, что каждый фильм, отдельно (скажем, с циклом for), не включен в массив allMovies.


По сути, я хочу иметь возможность вручную преобразовать свой класс Movie в Hashable, чтобы я мог выполнять на нем арифметику (как я делал до того, как начал внедрять RealmSwift для моей Movie модели) , Однако, как сейчас обстоят дела, кажется, что я не могу с Realm - если я не пропущу что-то очевидное ...

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