Multithreading 刷新一个领域的成本是多少?

Multithreading 刷新一个领域的成本是多少?,multithreading,realm,Multithreading,Realm,我已经阅读了文档,了解到在许多情况下,您不需要在领域实例上手动调用刷新。然而,在这个非常常见的场景中,它被证明是必要的,因为完成块可能在下一个运行循环开始之前查询领域 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [[RLMRealm defaultRealm] transactionWithBlock:^{ // Add some RLMObjects

我已经阅读了文档,了解到在许多情况下,您不需要在
领域
实例上手动调用
刷新
。然而,在这个非常常见的场景中,它被证明是必要的,因为完成块可能在下一个运行循环开始之前查询领域

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) 在
领域
上调用
刷新
的性能成本是多少

2) 在这种模式中只向领域添加一个对象可能是
无意义的在这个模式中添加了多少个对象之后,我会认为与在主线程上同步执行写事务相比有什么优势呢?

真是个好问题

1) 在
领域
上调用
刷新
的性能成本是多少

tl;博士提神不是很贵吗

成本将与在该线程上推进的
领域
实例支持的活动“访问器”的数量成正比。领域Objective-C中的访问器是
RLMObject
s、
RLMArray
s和
RLMResult
s

由于Realm使用的是隐藏的,与git的内部工作类似,调用
-[RLMRealm refresh]
是将该Realm的“当前事务指针”推进到最新的稳定状态的问题,很像
git pull
操作

值得注意的是,对于运行循环线程上的域,并且
autorefresh
设置为
YES
(这通常是主线程上的域的情况),
-[RLMRealm refresh]
将在运行循环的每次迭代中自动调用

因此,在绝大多数情况下,刷新一个领域对性能的影响可以忽略不计,除非该线程上有大量的活动“访问器”

2) 在这种模式中只向领域添加一个对象可能是没有意义的。在这个模式中添加了多少个对象之后,我会认为与仅在主线程上同步执行写事务相比有什么优势

tl;博士在后台执行写操作更安全

在绝大多数没有争用的情况下,在主线程上执行写事务的开销将低于平滑UI所需的1/60秒的阈值。然而,Realm中的写操作是阻塞的,这意味着如果在后台并发发生一个大型写事务,那么当从主线程并发写入时,这将阻塞主线程,这不太理想,因为它会导致UI阻塞或阻塞

出于这个原因,我们建议所有写事务,无论多么小和快速,都在后台线程上执行,除非您确定不会有任何争用

我意识到在后台线程上执行写操作由于Realm对访问器的严格线程限制执行而变得复杂,这就是为什么我们正在跟踪为异步写操作添加API的原因,允许在中跨线程安全地切换访问器


由于Realm中的读取操作不会被其他读取或写入阻止(感谢上面提到的MVCC!),所以在任何线程上执行这些操作都是完全可以接受的。

非常详细的回答,谢谢!然后我将继续使用后台写入模式。@jpsim在另一个块(如networking success/failure块)中使用transactionWithBlock怎么样?它比通常的提交事务好吗?transactionWithBlock实际上只是beginWriteTransaction&commitWriteTransaction的快捷方式