данные обновления области + DispatchQueue - PullRequest
0 голосов
/ 16 мая 2018

У меня есть обновление базы данных в фоновом режиме.Мои данные могут содержать ~ 2000 элементов, и для их обновления требуется время.

func updateData(items: [JSON], _ complete:@escaping() -> Void) {
    DispatchQueue.global(qos: .userInitiated).async {

       let currentModels = EgrnModel.getAllModels()
       var newModels: [EgrnModel] = []
       var toDelete: [EgrnModel] = []

       for model in currentModels {
           let contain = items.contains(where: {$0["id"].intValue == model.id})
           if !contain {
               toDelete.append(model)
           }
       }


       let realm = try! Realm()
       try! realm.write {
           for item in items {
               if let model = currentModels.first(where: {$0.id == item["id"].intValue}) {
                   model.update(item)
               }
               else {
                   newModels.append(EgrnModel(item))
               }
           }
           realm.delete(toDelete)
           realm.add(newModels)
       }

       DispatchQueue.main.async {
           complete()
       }
    }
}

, и у меня есть функция, в которой мне нужно мгновенно обновить данные.Когда я нажимаю галочку, я замираю.(Я думаю, потому что в это время другие данные обновляются в фоновом режиме)


func checkMark(index: Int) {

    let model = models[index]
    let realm = try! Realm()

    try! realm.write {
        model.needToUpdateOnServer = true
        model.lastEditUpdate = Date()
        model.read = true
    }
}

Я пытаюсь использовать следующий код, чтобы исправить зависание.Но в этом коде у меня происходит сбой Terminating app due to uncaught exception 'RLMException', reason: 'Realm accessed from incorrect thread.

func checkMark(index: Int) {

    let model = models[index]

    DispatchQueue.global(qos: .userInitiated).async {

        let realm = try! Realm()

        try! realm.write {
            model.needToUpdateOnServer = true
            model.lastEditUpdate = Date()
            model.read = true
        }
    }
}

1 Ответ

0 голосов
/ 26 мая 2019

Вам необходимо «переместить» объекты области из одного потока в другой, потому что объекты области не являются поточно-ориентированными, а ограничены потоками. Для этого вам нужно использовать ThreadSafeReference API.

Для решения этой проблемы выполните следующие действия:

  1. Создание расширения в классе области
extension Realm {
    func writeAsync<T : ThreadConfined>(obj: T, errorHandler: @escaping ((_ error : Swift.Error) -> Void) = { _ in return }, block: @escaping ((Realm, T?) -> Void)) {
        let wrappedObj = ThreadSafeReference(to: obj)
        let config = self.configuration
        DispatchQueue(label: "background").async {
            autoreleasepool {
                do {
                    let realm = try Realm(configuration: config)
                    let obj = realm.resolve(wrappedObj)

                    try realm.write {
                        block(realm, obj)
                    }
                }
                catch {
                    errorHandler(error)
                }
            }
        }
    }
}
  1. Используйте это в своем коде таким образом
func checkMark(index: Int) {

    let model = models[index]
    let realm = try! Realm()

    realm.asyncWrite(model) { realm, model in
        model.needToUpdateOnServer = true
        model.lastEditUpdate = Date()
        model.read = true
    }
}

СЧАСТЛИВЫЙ СВИФТ!

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