您可以在同一Realms上并行处理任意数量的线程,并且由于它们都有自己的快照,因此它们永远不会导致彼此看到不一致的状态

考虑一下写线程是否更改了某些值并且比读线程完成得更快,但是,由于读线程具有自己的快照,因此不会改变,因为写线程已完成了此操作,但是如果读线程的操作基于最新值,是否意味着读取线程无法执行正确的操作? 谢谢。

我的测试演示来描述我的困惑

包含我的测试演示以描述我的困惑的图像

#1楼 票数:2

文档“不一致”是指“部分修改”。 它们不能被部分修改,因为您始终可以看到通过事务更改创建的特定版本。

但是,更新不是跨线程立即进行的。

由于读取线程具有自己的快照,因此不会更改,因为对写入线程进行了什么操作,但是如果读取线程的操作基于最新值,那么这意味着读取线程无法执行正确的操作?

没错,这就是读取线程应使用集合通知的原因。

// from https://realm.io/docs/objc/latest/#collection-notifications
- (void)viewDidLoad {
  [super viewDidLoad];

  // Observe RLMResults Notifications
  __weak typeof(self) weakSelf = self;
  self.notificationToken = [[Person objectsWhere:@"age > 5"] addNotificationBlock:^(RLMResults<Person *> *results, RLMCollectionChange *changes, NSError *error) {
    if (error) {
      NSLog(@"Failed to open Realm on background worker: %@", error);
      return;
    }

    UITableView *tableView = weakSelf.tableView;
    // Initial run of the query will pass nil for the change information
    if (!changes) {
      [tableView reloadData];
      return;
    }

    // Query results have changed, so apply them to the UITableView
    [tableView beginUpdates];
    [tableView deleteRowsAtIndexPaths:[changes deletionsInSection:0]
                     withRowAnimation:UITableViewRowAnimationAutomatic];
    [tableView insertRowsAtIndexPaths:[changes insertionsInSection:0]
                     withRowAnimation:UITableViewRowAnimationAutomatic];
    [tableView reloadRowsAtIndexPaths:[changes modificationsInSection:0]
                     withRowAnimation:UITableViewRowAnimationAutomatic];
    [tableView endUpdates];
  }];
}
- (void)dealloc {
  [self.notificationToken stop];
}

除此之外,事务始终“创建最新版本”(并且一次只能有1个事务),因此写事务中的查询不能过时。

dispatch_async(writeQueue, ^{
    [[RLMRealm defaultRealm]] transactionWithBlock:^{
         Cinema* b = [Cinema allObjects].firstObject; // query cannot be out of date
         ...

显然,这并不意味着你应该在UI线程上执行事务只是碰到它的版本。 为此使用通知令牌。

#2楼 票数:1

是的,这是正确的。 如果要确保始终从Realm中获得一致的数据,请不要从单独的线程中同时访问它,因为在一个线程上完成的写事务不会反映在另一个线程上。 在您的示例中也可以看到这种行为。

除非您有大量对象要读取/写入,否则也不需要异步访问领域。 如果您要使用大量对象,以致您的查询/写入事务将花费几秒钟,因此同步执行它们会阻止UI更新太长时间,请确保仅从单个线程访问Realm,并确保您的异步读/写操作未并行运行。

  ask by ynot16 translate from so

未解决问题?本站智能推荐:

1回复

从错误的线程访问领域

我写了下面的方法来处理文件的下载。 但是,这总是引发错误,指出从不正确的线程访问了Realm。 我不知道是什么原因造成的。 有任何想法吗?
1回复

ObjC领域线程问题

我有一个具有发布方法的Realm对象(LFEMemory)。 调用publish方法时,我必须将图像上传到AWS,然后使用Amazon返回的URL更新对象。 问题是,当该块从AWS返回时,我自己的LFEMemory对象不再是线程安全的。 (实际上,通常是在应用正常运行期间,但如果我使用
1回复

将对象从另一个线程保存到领域中?

当我尝试在后台保存对象时,出现异常-“从错误的线程访问了领域”。 这是领域的初始化-“ self.realm = [RLMRealm defaultRealm]” 我在后台将对象保存到领域的方法:
1回复

领域在后台线程上获取对象并传递给主线程

我想在后台线程上获取大量对象,但是由于我无法将它们传递给主线程 获取代码 如何在后台执行获取并将对象传递给主线程,以使对性能的影响最小 我可以获取主键,然后在主线程上进行重新提取,但这与直接获取它们的性能相同(可能甚至更慢)
1回复

iOS应用中多个对象的多个领域

我们的iOS应用程序中有许多对象,它们相互之间紧密引用到嵌套级别。 我们的应用程序是多线程的。 使用领域(目标C)作为数据库选择时,出现了以下问题,并期待得到答案: 我们应该使用单个领域还是多个领域,每个对象一个? 对于单/多方法,我们是否需要担心内存不足的问题? 请注意,我们
1回复

主线程看不到后台线程所做的更改

我试图在主线程上看到后台线程所做的更改时遇到了麻烦。 当我的completionBlock被调用时,我无法找到领域对象。 请记住,使用GCD将completionBlock分派到主线程上,根据文档,主线程应该自动查看其他线程完成的写入提交。 编辑:我在Realm 0.98.2和0.98
1回复

如何在iOS中的线程之间传递RLMObject?

我有10000个RLMObjects的RLMArray,可以在按钮触摸事件时按其属性排序。 我想通过GCD将排序过程踢回到后台线程,并保持UI流畅。 领域不是线程安全的,因此一旦我将更新的RLMArray返回主线程,它就会崩溃。 这样做的最佳方法是什么? 谢谢
1回复

使用Realm数据填充UITableView(表格)?

我的解决方案不起作用 - 我使用领域获取数据将其存储为数组并在cellForRowAtIndexPath:重用此数组。 问题是我应该在后台线程中获取数据,但在主线程中填充表。 注意:我已经读过,如果我在当前线程中获取领域数据,那么我只能在这个线程中使用它们。 否则我应该为我需要的每个领域对象创建Th