【发布时间】:2021-08-22 00:53:43
【问题描述】:
我想在我的 Realm 数据库上执行某些写入操作,而无需通知整个 SwiftUI 应用程序中的任何观察者。原因是我正在将我的 Realm 数据库同步到 CloudKit,当 CloudKit 响应记录已成功更新时,我设置了 Realm 对象的 modified 属性以匹配服务器。我不希望由此触发通知,因为这是用户已经在 UI 中进行的更改,并且同步往返不应中断 UI。
由于我的观察者遍布我的应用程序中的各种ObservableObjects,我将所有令牌合并到我在应用程序首次启动时初始化的单例中。
class RealmSetup{
static let shared = RealmSetup()
var tokenAlpha: NotificationToken? = nil
var tokenBravo: NotificationToken? = nil
}
然后他们像这样在其他地方设置:
class AlphaModel: ObservableObject{
static let shared = AlphModel()
init(){
let realm = try! Realm()
RealmSetup.shared.tokenAlpha = realm.objects(Alpha.self).observe { [weak self] _ in
self?.objectWillChange.send()
}
}
}
...同样:
class BravoModel: ObservableObject{
static let shared = BravoModel()
init(){
let realm = try! Realm()
RealmSetup.shared.tokenBravo = realm.objects(Bravo.self).observe { [weak self] _ in
self?.objectWillChange.send()
}
}
}
这是我写作的精髓:
let realm = try! Realm()
realm.beginWrite()
//Do a bunch of record changes...
//Find the non-nil notification tokens and try not to notify them
var tokensReady = [NotificationToken]()
for token in [RealmSetup.shared.tokenAlpha, RealmSetup.shared.tokenBravo]{
if let ready = token{
tokensReady.append(ready)
}
}
try! realm.commitWrite(withoutNotifying: tokensReady)
我遇到的问题是,当同步完成并尝试提交写入时,我遇到了崩溃:
不正确的领域:只能跳过正在修改的领域的通知。
显然,令牌与写入不在同一个领域。据我所知,我的 ObservableObjects 位于主线程上,但如果我将编写代码包装在 DispatchQueue.main.async { ... } 中,我仍然会崩溃。
我不是线程方面的专家,所以我有点困惑。我怎样才能确保所有这些事情都发生在同一个线程上?还是有更简单的方法来做我想做的事情?
【问题讨论】:
-
Realm 可以在不通知观察者的情况下写入数据。见write(withoutNotifying:_:)。我很好奇为什么两个独立的数据库? Realm 和 iCloud (CloudKit),Realm 什么时候可以处理所有这些?您介意分享一下用例吗?
-
是的,我在我的问题中提到了
withoutNotifying选项并解释了相关的崩溃。我使用 CloudKit 是因为我已经熟悉它了,它是免费的、稳定的,而且 API 不需要在我的应用程序中进行身份验证。由于潜在的成本,我对使用 MongoDB Realm 同步感到紧张,并且过度依赖单一供应商(我过去一直被这种情况所困扰)。 -
我明白了。好吧,如果您想专注于一个解决方案,请放心,Realm 可以处理整个事情。我提到了 withoutNotifying,因为它确实有效——我们一直在使用它。代码通常看起来不错 - 尽管 ObservableObject 与 ObservedRealmObject 可能存在问题。
标签: realm