领域:从后台线程添加,更新,删除操作并在主线程

时间:2016-01-19 15:02:14

标签: ios thread-safety realm

我正在为我的应用程序使用Realm,我希望能够在后台线程上查询结果并在主线程上接收它们。 实现这一目标的最佳方法是什么?什么是使用领域的最佳实践(主线程和背景有不同的方法?主要在应用程序中使用领域的静态实例?可能是另一种好方法?)

我已阅读并看到此选项可用: - 将领域对象解析为我自己的对象并返回它们(结果的副本)。 - 返回对象的密钥并从主线程中再次查询。

感谢任何人都能给我的帮助,我认为领域有很大的潜力,但缺乏良好的教程和最佳实践。

1 个答案:

答案 0 :(得分:6)

首先,由于Realm在大多数情况下足够快,因此您无需在后台运行查询。

所以基本策略是;在后台更新,在主线程中获取。

最常用的方法是利用实时更新的功能。 RLMResultsResults有实时更新。您可以通过查询保留RLMResults / Results个实例。然后,您将在后台线程中进行任何更改,更改会在提交时自动通知并自动反映。

// Hold RLMResults for the data source
self.array = [[DemoObject allObjects] sortedResultsUsingProperty:@"date" ascending:YES];

// Reload table view when changed by other threads
__weak typeof(self) weakSelf = self;
self.notification = [RLMRealm.defaultRealm addNotificationBlock:^(NSString *note, RLMRealm *realm) {
    [weakSelf.tableView reloadData];
}];

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // RLMResults is updated automatically
    return self.array.count;
}

// Update in background 
- (void)backgroundAdd
{
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    // Import many items in a background thread
    dispatch_async(queue, ^{
        // Get new realm and table since we are in a new thread
        RLMRealm *realm = [RLMRealm defaultRealm];
        [realm beginWriteTransaction];
        for (NSInteger index = 0; index < 5; index++) {
            // Add row via dictionary. Order is ignored.
            [DemoObject createInRealm:realm withValue:@{@"title": [self randomString],
                                                         @"date": [self randomDate]}];
        }
        [realm commitWriteTransaction];
    });
}

有关详情,请参阅table view example in Realm's repo

如果有少数情况下Realm在主线程上获取时速度不够快,你可以在后台线程中获取。然后聚合一个主键数组。然后传递数组并使用主键重新获取主线程。

仅供参考:我们正在努力增加对异步运行查询的支持https://github.com/realm/realm-cocoa/pull/2842 如果此功能将被释放,您不需要聚合主键并重新获取。