您可以让任意数量的线程并行处理同一个Realms,并且由于它们都有自己的快照,因此它们永远不会导致彼此看到不一致的状态
考虑写入线程是否改变了某些值并且比读取线程更快地完成,但是,由于读取线程有自己的快照,因此它不会改变,因为在写入线程上做了什么,但是如果读取线程的操作是基于最新的值,所以这意味着读取线程无法正常运行? thx求助。
我的测试演示来描述我的困惑
答案 0 :(得分: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];
}
除此之外,交易始终&#34;创建最新版本&#34; (并且一次只能有一个事务),因此写事务中的查询不能过时。
dispatch_async(writeQueue, ^{
[[RLMRealm defaultRealm]] transactionWithBlock:^{
Cinema* b = [Cinema allObjects].firstObject; // query cannot be out of date
...
显然, NOT 意味着你应该在UI线程上执行事务只是为了碰撞它的版本。使用通知令牌。
答案 1 :(得分:1)
是的,这是正确的。如果要确保始终从Realm获取一致的数据,请不要从单独的线程同时访问它,因为在一个线程上完成的写入事务不会反映在另一个线程上。这也是您的示例中可以看到的行为。
除非您有大量的对象要从中读取/写入,否则也不需要异步访问域。如果你想使用如此大量的对象,你的查询/写入事务需要几秒钟,因此同步执行它们会阻止UI更新太长时间,请确保只从单个线程访问Realm并确保你的异步读/写操作没有并行运行。