在写入事务中注册领域通知

Jon*_*gel 8 realm swift

据我所知,你不能注册一个Realm .observe对象或集合上块,如果Realm是写事务.

如果主线程上发生了所有事情,这将更容易管理,但我经常遇到此异常,因为我更喜欢将我的JSON解析移交给后台线程.这非常有用,因为我不必陷入主线程并且使用Realm漂亮的通知系统,如果我已经注册以监听这些更改,我可以收到所有修改的通知.

现在,如果我要添加一个观察块,我会检查以确保我Realm不在这样的写入事务中:

    guard let realm = try? Realm(), !realm.isInWriteTransaction else {
        return
    }

    self.myToken = myRealmObject.observe({ [weak self] (change) in
        //Do what ever
    }
Run Code Online (Sandbox Code Playgroud)

这成功地防止了这种异常.但是,除非我有点创意,否则我永远不会有机会重新注册此令牌.

Realm团队是否有关于更好模式的代码示例/建议以避免此异常?我没有成功注册令牌的任何技巧?

Lep*_*ron 1

除了标准函数之外,我Results通常还使用扩展来避免这种情况。当我们的数据负载越来越大时,这个问题就出现了。

虽然我们现在重写了观察函数逻辑,但此扩展是一个临时解决方案,可以从一开始就避免崩溃。想法很简单:当当前处于写事务中时,再试一次。

import Foundation
import RealmSwift

extension Results {
    public func safeObserve(on queue: DispatchQueue? = nil,
                            _ block: @escaping (RealmSwift.RealmCollectionChange<RealmSwift.Results<Element>>) -> Void)
    -> RealmSwift.NotificationToken {
        // If in Write transaction, call it again
        if self.realm?.isInWriteTransaction ?? false {
            DispatchQueue.global().sync {
                Thread.sleep(forTimeInterval: 0.1) // Better to have some delay than a crash, hm?
            }
            return safeObserve(on: queue, block)
        }
        // Aight, we can proceed to call Realms Observe function
        else {
            return self.observe(on: queue, block)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后称呼它为

realmResult.safeObserve({ [weak self] (_: RealmCollectionChange<Results<AbaPOI>>) in
    // Do anything
})
Run Code Online (Sandbox Code Playgroud)