当保存对象时,从错误线程访问Realm。

3

我正在使用Realm来开发一个消息应用程序。我需要修改一些查询到的对象,例如,如果对象是媒体消息并且还没有缩略图,则下载并尝试保存它到该对象中。

由于这个操作是在for循环中进行的,因此可能会同时有多个下载正在运行。但是,即使我为每个对象保存分配了新实例的默认Realm,为什么会抛出此异常呢?

我尝试将下载块包装在dispatch_async中,以为可能是竞争条件或其他相关问题,但是没有成功,仍然抛出异常:

'RLMException', reason: 'Realm accessed from incorrect thread'

RLMResults *messages = [[Message objectsWhere:@"jabberID = %@", self.recipientJID] sortedResultsUsingProperty:@"date" ascending:YES];

for (Message *message in messages) {
  if (!message.hasThumbData) {

    [self downloadMedia:message.remoteMediaURL success:^(NSData *mediaData) {

      RLMRealm *realm = [RLMRealm defaultRealm];
      [realm beginWriteTransaction];
      message.hasThumbData = YES;
      message.thumbData = mediaData;
      [realm commitWriteTransaction]; 

    } failure:^(NSError *error) {
      NSLog(@"Error downloading media: %@", error.description);
    }];

  }
} 
1个回答

2

持久化的 Realm 对象只能在读取它们的线程上进行读写操作。假设 [self downloadMedia:success:failure:] 方法的成功回调被调用的线程不同于读取 messages 的线程,则意味着你不能在该块中使用 message。为当前线程创建一个新的 RLMRealm 实例不会对捕获的变量产生任何影响。


成功块在主线程上被调用,RLMResults也是如此。 - Marcos Curvello
@MarcosCurvello,你找到任何解决方案了吗?我也有同样的情况。 - Nik
我没有找到解决方案。我觉得很有趣,因为我知道所有的操作都是在主线程上执行的。这里有什么建议吗@Thomas Goyne? - Marcos Curvello
@segiddins 不,这是有可能的。当用户点击已经有缩略图的媒体以下载全分辨率时,我正在使用相同的下载块,在这种情况下,我能够重新保存我的RLMObject。 - Marcos Curvello
在这种情况下,当异常被抛出时,您能否分享一下回溯信息? - segiddins
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接