Realm swift 通知停止触发

iOS*_*evZ 9 realm ios swift

我为实时结果对象设置了一个观察者。

let token = realm.objects(RealmObject.self).observe(on: realmQueue) { changeset in
   print(changeset)
}
Run Code Online (Sandbox Code Playgroud)

它在大多数情况下按预期工作,当我在领域数据库中/向领域数据库添加/删除或编辑 RealmObject 类型对象时,它会触发。当我尝试用新数组替换整个对象数组时,会出现我的问题。基本上我所做的是将 RealmObjects 类型的所有对象删除,然后添加新的 RealmObjects 数组。现在的问题是,如果我执行删除操作并在一个写入事务中添加通知机制似乎会中断,则不会触发此操作。另一方面,如果我将删除分开并添加到不同的写入事务中,那么一切都会处理通知(除了在这种情况下我按预期收到两个通知,但这不是我想要的)。我是否错过了什么并做错了什么?

// triggers notifications
let objectsToDelete = realm.objects(RealmObject.self)
try realm.write {
    if !objectsToDelete.isEmpty {
        realm.delete(objectsToDelete)
    }
}
try realm.write {
    realm.add(objects)
}
// doesn't trigger notification
let objectsToDelete = realm.objects(RealmObject.self)
try realm.write {
    if !objectsToDelete.isEmpty {
        realm.delete(objectsToDelete)
    }
    realm.add(objects)
}
Run Code Online (Sandbox Code Playgroud)

编辑:经过进一步调查,似乎这只发生在特定情况下。当用相同数量的项目和相同的主键替换项目时(即使其他一些属性不同)。

class RealmObject: Object {
    @objc dynamic var primary: String!
    @objc dynamic var summary: String!
    
    override class func primaryKey() -> String? {
        return "primary"
    }
}

extension RealmObject {
    convenience init(summary: Int, uuid: String = UUID().uuidString) {
        self.init()
        self.primary = uuid
        self.summary = "Object nr. \(summary)"
    }
}
let sharedKeys = [UUID().uuidString, UUID().uuidString, UUID().uuidString]
let initialObjects = [RealmObject(summary: 0, uuid: sharedKeys[0]),RealmObject(summary: 1, uuid: sharedKeys[1]),RealmObject(summary: 2, uuid: sharedKeys[2])]
let replaceObjects = [RealmObject(summary: 3, uuid: sharedKeys[0]),RealmObject(summary: 4, uuid: sharedKeys[1]),RealmObject(summary: 5, uuid: sharedKeys[2])]
Run Code Online (Sandbox Code Playgroud)

And*_*ent 0

这敲响了警钟(2015-2017 年我在 Realm C# 团队工作)。

我相当确定这是因为对主键及其事务中的使用进行了优化,并结合了通知结构的构建方式。严格来说,这是一个错误。您可能期望这些会以“删除+添加”或“更改”记录的形式出现在通知中。

您正在与关于如何使用主键以及旨在使它们以惊人的速度运行的优化的深层核心假设作斗争。我强烈怀疑它会得到修复。

切换到非主键但索引字段可能会解决这个问题,但会使代码的其余部分变得复杂,抱歉。

您也可能根本不需要对这些内容建立索引,具体取决于您的数据量。Realm 的搜索速度非常快,因此我总是建议人们首先尝试非索引搜索,看看是否足够。