Объект Realm в обработчике завершения: «Доступ к области осуществляется из неверного потока». - PullRequest
0 голосов
/ 11 ноября 2019

Я разрабатываю SDK, который в основном пишет методы-оболочки, скрывающие вызовы API, и возвращает объекты данных в завершении. Обработчик:

public static func getDogs(token: String?, completionhandler: @escaping (Int?, [Dog]?) -> Void) {
}

Собаки - это объекты области:

public class Dog: Object {
    @objc public dynamic var name: String?
    @objc public dynamic var age: Int = 0
}

Теперь, когда япопытаться получить доступ к Dogs при вызове getDogs,

getDogs(token: token) { status, dogs in
    \\ Access Dog[0]
}

Как и ожидалось, я получаю RealmException:

*** Завершение работы приложения из-за необработанного исключения 'RLMException', причина: 'Доступ к Realm из неверного потока.'

Теперь, как я могу передать такой список объектов Realm в обработчик завершения и получить к нему доступ позже, не получив это исключение? Я знаю о ThreadSafeReference, но не хочу, чтобы конечный пользователь читал руководство по зависимости от третьих лиц, прежде чем использовать SDK. Какова должна быть лучшая практика здесь? Очевидно, я не могу отправить список объектов Realm. Кроме того, исходя из соображений дизайна для независимой структуры, я не должен предполагать, что наши конечные пользователи должны знать Realm apriori. Поддержка области должна быть полезной, и не в первую очередь.

Другой вариант, который у меня есть, - это сохранить две копии одной и той же модели данных: обычный объект и объект Realm. Но это увеличит время разбора.

1 Ответ

0 голосов
/ 11 ноября 2019

Как указано в документации Realm :

Экземпляры RLMRealm, RLMResults или RLMArray или управляемые экземпляры RLMObject ограничены потоками, то есть они могут быть толькоиспользуется в потоке, в котором они были созданы, в противном случае выдается исключение

Чтобы избежать этого исключения, вы должны создавать экземпляр Realm каждый раз, когда он вам нужен, и убедиться, что вы его выпускаете. с авто-релизным бассейном.

// Query and update from any thread
autoreleasepool {
    let realm = try! Realm()
    let theDog = realm.objects(Dog.self).filter("age == 1").first
    try! realm.write {
        theDog!.age = 3
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...