我正在为我的应用程序使用Realm,我希望能够在后台线程上查询结果并在主线程上接收它们。 实现这一目标的最佳方法是什么?什么是使用领域的最佳实践(主线程和背景有不同的方法?主要在应用程序中使用领域的静态实例?可能是另一种好方法?)
我已阅读并看到此选项可用: - 将领域对象解析为我自己的对象并返回它们(结果的副本)。 - 返回对象的密钥并从主线程中再次查询。
感谢任何人都能给我的帮助,我认为领域有很大的潜力,但缺乏良好的教程和最佳实践。
答案 0 :(得分:6)
首先,由于Realm在大多数情况下足够快,因此您无需在后台运行查询。
所以基本策略是;在后台更新,在主线程中获取。
最常用的方法是利用实时更新的功能。
RLMResults
和Results
有实时更新。您可以通过查询保留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 如果此功能将被释放,您不需要聚合主键并重新获取。