realm事务完成后如何触发KVO?
How to make KVO trigger after realm transaction is completed?
我有 Group
和 Thread
的模型,它们之间的关系类似于
Group 1-Many Thread
我有这个代码,当发生离开组时会触发
[RLMRealm transactionWithBlock:^(RLMRealm *realm) {
// Clear all unread in threads
RLMResults<Thread *> *threads = [Thread allThreadsInGroupID:self._id];
for (Thread *thread in threads) {
[thread clearLocalUnreads]; // <-- Trigger KVO for thread
}
// Delete group
[realm deleteObject:self];
} error:nil];
在 ViewController
中,我使用 KVO
观察 Thread
的一些 属性 并在发生变化时调用此方法
- (void)threadsControllerDidReloadData:(ThreadsController *)controller {
// To prevent realm notification infinite loop in WorkspaceKPIDatasource
if ([self.tableView.dataSource isKindOfClass:[WorkspaceTableViewController class]]) {
WorkspaceTableViewController *workspaceTVC = (WorkspaceTableViewController *)self.tableView.dataSource;
if ([workspaceTVC.contentDatasource isKindOfClass:[WorkspaceThreadsDatasource class]]) {
[self.tableView reloadData];
// Fix crash when reloadData is try to access group during leave since calling reloadData, the update
// will not happen immediately. This line will force the layout to update immediately result in calling
// - cellForRowAtIndexPath in the same run loop to prevent accessing invalidate group
[self.tableView.superview layoutIfNeeded]; // <-- This solve crash
}
[workspaceTVC refreshHeader];
}
}
这里有两个问题
- KVO 在没有领域交易完成的情况下被触发
cellForRowAtIndexPath
在调用 reloadData
后不会 运行 立即导致即使 KVO
在组删除之前触发,当单元格布局时它崩溃为什么试图访问无效组。
我现在选择选项 2 来解决这个问题,因为它最简单。
但是我觉得比较合理的做法是让KVO
在交易完成后才触发。在那种情况下,无论交易中发生什么,都将在最后分组。
因为这个问题导致我认为领域的 KVO
可能会导致一些问题,比如交易中途失败但不知何故 KVO
已经触发,因为更改在对象级别。
但是通过阅读文档here。在我看来 KVO
会在写入事务发生时调用,但我不知道为什么在我的情况下 Thread
被更新并且 - threadsControllerDidReloadData:
被调用为什么 [group isInvalidated]
仍然return NO
那个方法
从它的声音来看,KVO 可能不适合您要完成的任务。
如果您在 table 视图中与数据交互,使用 Realm's fine-grained notifications 注册更改可能更合适。该系统旨在与 table 视图一起使用,并将延迟并在更适合更新 table 视图内容的时间发送通知。
我有 Group
和 Thread
的模型,它们之间的关系类似于
Group 1-Many Thread
我有这个代码,当发生离开组时会触发
[RLMRealm transactionWithBlock:^(RLMRealm *realm) {
// Clear all unread in threads
RLMResults<Thread *> *threads = [Thread allThreadsInGroupID:self._id];
for (Thread *thread in threads) {
[thread clearLocalUnreads]; // <-- Trigger KVO for thread
}
// Delete group
[realm deleteObject:self];
} error:nil];
在 ViewController
中,我使用 KVO
观察 Thread
的一些 属性 并在发生变化时调用此方法
- (void)threadsControllerDidReloadData:(ThreadsController *)controller {
// To prevent realm notification infinite loop in WorkspaceKPIDatasource
if ([self.tableView.dataSource isKindOfClass:[WorkspaceTableViewController class]]) {
WorkspaceTableViewController *workspaceTVC = (WorkspaceTableViewController *)self.tableView.dataSource;
if ([workspaceTVC.contentDatasource isKindOfClass:[WorkspaceThreadsDatasource class]]) {
[self.tableView reloadData];
// Fix crash when reloadData is try to access group during leave since calling reloadData, the update
// will not happen immediately. This line will force the layout to update immediately result in calling
// - cellForRowAtIndexPath in the same run loop to prevent accessing invalidate group
[self.tableView.superview layoutIfNeeded]; // <-- This solve crash
}
[workspaceTVC refreshHeader];
}
}
这里有两个问题
- KVO 在没有领域交易完成的情况下被触发
cellForRowAtIndexPath
在调用reloadData
后不会 运行 立即导致即使KVO
在组删除之前触发,当单元格布局时它崩溃为什么试图访问无效组。
我现在选择选项 2 来解决这个问题,因为它最简单。
但是我觉得比较合理的做法是让KVO
在交易完成后才触发。在那种情况下,无论交易中发生什么,都将在最后分组。
因为这个问题导致我认为领域的 KVO
可能会导致一些问题,比如交易中途失败但不知何故 KVO
已经触发,因为更改在对象级别。
但是通过阅读文档here。在我看来 KVO
会在写入事务发生时调用,但我不知道为什么在我的情况下 Thread
被更新并且 - threadsControllerDidReloadData:
被调用为什么 [group isInvalidated]
仍然return NO
那个方法
从它的声音来看,KVO 可能不适合您要完成的任务。
如果您在 table 视图中与数据交互,使用 Realm's fine-grained notifications 注册更改可能更合适。该系统旨在与 table 视图一起使用,并将延迟并在更适合更新 table 视图内容的时间发送通知。