如何在具有深度层次结构的Realm(Swift)中优化结果更改侦听器的性能?

时间:2019-06-18 10:14:37

标签: ios swift realm

从项目最早开始,我们就使用Realm(当前版本为3.12.0的快速绑定)。在1.0 Realm之前的某些早期版本中,Results提供了Results的更改侦听器,而没有实际提供changeSets。
我们经常使用它来确定特定的Realm列表是否发生了变化。

后来RxSwift的人们将此API与changeSet提供方法进行了交换。为了确定特定列表中的任何内容(插入,删除,修改)是否发生更改,我们不得不进行切换,现在正在滥用此API。

我们与Results一起编写了自己的public var observable: Observable<Base> { return Observable.create { observer in let token = self.base.observe { changes in if case .update = changes { observer.onNext(self.base) } } observer.onNext(self.base) return Disposables.create(with: { observer.onCompleted() token.invalidate() }) } } 变更监听实现,如下所示:

someRealm.objects(SomeObject.self).filter(<some filter>).rx.observable
    .subscribe(<subscription code that gets called on every update>)
    //dispose code missing

现在我们要在列表上进行连续更新时,我们就这样订阅:

RealmCollection

我们在List上写了扩展名,以便我们也可以订阅RxRealm类型。

这个概念等同于Car的方法。

所以现在在我们的应用中,我们有很多要订阅的过滤列表/结果。

当数据越来越多时,在将某些内容写入数据库后以视觉方式看到更改时,我们会注意到性能显着下降。

例如: 假设我们有一个Bool领域对象类,该类具有一些属性以及一些1-n和一些1-to-1关系。属性之一是isDriving,即isDriving。 现在,我们有许多汽车存储在数据库中,还有一堆变更侦听器,这些侦听器使用不同的过滤器列出了cars集合的变更(集合观察者在侦听changeSet,以了解列表是否已更改)。 如果我乘某个列表中的一辆车并将false的属性从true设置为Car(重要:我们确实在后台编写),则理想情况下是更改侦听器快速启动,并且我对主线程上的写入 几乎立即有了正确的响应。

于2019-06-19添加了修改:


让场景变得更加真实: 让我们在层次结构中进行一些更改,比方说轮胎制造商的名称。假设List<Tire>具有TireManufacturer具有Manufacturer has a. Now we're still listing to名称collection changes with some more or less complex filters applied. Then we're changing the name of a结果Realm制造商`已连接到该过滤列表中的其中一辆汽车的轮胎之一。
这还能很快吗?


很显然,当变更监听器所附加的结果/列表的长度变长时,.observe的内部变更监听器需要更长的时间来计算差异并在以后触发。 因此,在写完之后,我们会看到变化-在最坏的情况下-要晚得多。

在我们的情况下,这是不可接受的。因此,我们正在考虑不同的方案。 一种情况是不再在列表/结果上使用Realm.observe并切换到Prof Pic.jpeg, profile/Prof Pic.jpeg,这会在领域中的任何内容发生任何更改时都触发,这并不理想,但这很快,因为更改计算过程被跳过。

我的问题是:我该怎么做才能解决整个难题,并使我们的应用程序再次快速运行?

关键是线程。由于我们的设计,我们总是在后台编写文字。因此,写入本身应该非常快,但是随后这些东西需要与Realms打开的其他线程同步。 以我的理解,这是在对所有结果进行更改检测之后发生的,对吗? 因此,当我在另一个线程上进行读取时,数据仅在线程同步后才刷新,这在发出所有通知之后才会发生。但是我不确定当前是否之前进行过同步,这会更棒,现在还没有对其进行测试。

0 个答案:

没有答案