我已阅读文档并了解,在许多情况下,您不需要在 Realm
实例上手动调用 refresh
。然而,在这种非常常见的场景中,它被证明是必要的,因为完成 block 可能会在下一个运行循环开始之前查询 Realm 。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[[RLMRealm defaultRealm] transactionWithBlock:^{
// Add some RLMObjects
}];
if (completion) {
dispatch_async(dispatch_get_main_queue(), ^{
[[RLMRealm defaultRealm] refresh]; // necessary if it queries realm
completion();
});
}
});
我以为我通过在后台线程上执行写入操作来成为一个好公民,但现在我必须调用 refresh
,我想知道此调用所涉及的开销是否违背了这一点进行后台处理。
所以我的问题是:
1) 在 Realm
上调用 refresh
的性能成本是多少?
2) 在此模式中仅向 Realm 添加一个对象可能是 无意义。在这种模式中添加多少个对象后,我会发现比仅在主线程上同步执行写入事务的替代方案有优势吗?
最佳答案
非常好的问题!
1) What is the performance cost of calling
refresh
on theRealm
?
tl;博士;刷新没那么贵
成本将与该线程上推进的 Realm
实例支持的事件“访问器”数量成比例线性。 Realm Objective-C 中的访问器是 RLMObject
、RLMArray
和 RLMResult
。
由于 Realm 使用 MVCC versioning system在幕后,与 git 的内部工作原理类似,调用 -[RLMRealm refresh]
是将 Realm 的“当前事务指针”推进到最新的稳定状态,就像 git pull
操作。
值得注意的是,对于具有运行循环且 autorefresh
设置为 YES
的线程上的 Realms(主线程上的 Realms 通常是这种情况),-[RLMRealm刷新]
将在运行循环的每次迭代时自动调用。
因此,在绝大多数情况下,刷新 Realm 对性能的影响可以忽略不计,除非该线程上有非常大量的实时“访问器”。
2) Adding just one object to the realm in this pattern probably is pointless. After adding how many objects in this pattern would I see an advantage over the alternative of just performing the write transaction on the main thread synchronously?
tl;博士;在后台执行写入更安全
在没有争用的绝大多数情况下,在主线程上执行写入事务的开销将低于流畅 UI 所需的 1/60 秒阈值。 但是 Realm 中的写入是阻塞,这意味着如果后台并发发生大型写入事务,这会在从主线程并发写入时阻塞主线程,这不太理想,因为它会导致 UI 断断续续或阻塞。
出于这个原因,我们建议所有写入事务,无论多小多快,都在后台线程上执行,除非您确定不会出现任何争用。
我意识到,由于 Realm 对访问器执行严格的线程限制,在后台线程上执行写入会变得复杂,这就是为什么我们正在跟踪为异步写入添加 API,以允许跨线程安全地切换访问器 #3136 .
由于 Realm 中的读取操作不会被其他读取或写入阻塞(感谢上面提到的 MVCC!),因此在任何线程上执行这些操作是完全可以接受的。
关于multithreading - 刷新 Realm 的成本是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36202799/