Realm - 在后台线程上批量更新 RLMResults

Posted

技术标签:

【中文标题】Realm - 在后台线程上批量更新 RLMResults【英文标题】:Realm - Batch update RLMResults on background thread 【发布时间】:2017-03-11 21:45:43 【问题描述】:

我有需要迭代的 RLMResults,执行一个可能“长时间运行”的下载任务(足够长,它不应该在主线程上),并使用此下载的结果更新每个对象。我尝试过的最新迭代(在搜索文档以获得答案之后)是这样的,虽然这显然不能按预期工作,但它是演示目的的起点:

RLMResults *objectsToSaveImagesFor = [self allObjectsToSaveImagesFor];
for (Object *object in objectsToSaveImagesFor) 
    RLMThreadSafeReference *objectRef = [RLMThreadSafeReference referenceWithThreadConfined:object];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
        RLMRealm *realm = [RLMRealm realmWithConfiguration:self.realm.configuration error:nil];

        Object *threadSafeObject = [realm resolveThreadSafeReference:objectRef];

        BOOL success = [self downloadImageForObject:threadSafeObject];

        [realm transactionWithBlock:^
            threadSafeObject.imageSaved = success;
        ];
    );

我已经尝试了十多次迭代,但无法找出规范的 Realm 方法来做我想做的事情,即下载大量图像(数千张)并更新我的每个 Realm 对象都带有后台线程上的下载结果。

【问题讨论】:

【参考方案1】:

不要为RLMResults 中的每个对象创建和解析线程安全引用,只需执行一次:

RLMResults *objectsToSaveImagesFor = [self allObjectsToSaveImagesFor];
RLMThreadSafeReference *objectsRef = [RLMThreadSafeReference referenceWithThreadConfined:objectsToSaveImagesFor];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
    RLMRealm *realm = [RLMRealm realmWithConfiguration:self.realm.configuration error:nil];
    RLMResults *objectsToSaveImagesFor2 = [realm resolveThreadSafeReference:objectsRef];
    for (Object *object in objectsToSaveImagesFor2) 
      BOOL success = [self downloadImageForObject:threadSafeObject];
      [realm transactionWithBlock:^
        object.imageSaved = success;
      ];
    
);

【讨论】:

我没想到你可以得到一个对整个 RLMResults 的线程安全引用...做到了,谢谢!

以上是关于Realm - 在后台线程上批量更新 RLMResults的主要内容,如果未能解决你的问题,请参考以下文章

保存子上下文时获取 NSFetchedResultsController 的批量更新

如何在后台队列中获取对象的领域结果,然后在主线程上使用它

Realm.js - default.realm 已经在当前线程上以不同的模式打开

错误:路径 '/var/.../default.realm' 的领域已经在当前线程上以不同的模式打开

核心数据在后台线程上缓慢处理更新

在后台线程中更新托管对象上下文