如何确保在使用 MagicalRecord 3.0 保存后台线程后通知 NSFetchedResultsController
Posted
技术标签:
【中文标题】如何确保在使用 MagicalRecord 3.0 保存后台线程后通知 NSFetchedResultsController【英文标题】:How to be sure NSFetchedResultsController is notified after background thread save with MagicalRecord 3.0 【发布时间】:2014-07-19 22:02:19 【问题描述】:我正在使用带有 ClassicWithBackgroundCoordinatorSQLiteMagicalRecordStack
堆栈和 NSFetchedResultsController 的 MagicalRecord 3.0。在 Magical Record 使用后台线程(通过[MagicalRecord saveWithBlock:]
)保存新的相关数据后,NSFetchedResultsController 没有更新的问题。
栈就这样初始化了:
MagicalRecordStack *stack = [[ClassicWithBackgroundCoordinatorSQLiteMagicalRecordStack alloc] initWithStoreNamed:@"Mailstrom.sqlite"];
[MagicalRecordStack setDefaultStack:stack];
NSFetchedResultsController 初始化如下:
NSFetchRequest *request = [NSClassFromString(_entityName)
MR_requestAllSortedBy:_weightProperty
ascending:NO
withPredicate:[NSPredicate predicateWithFormat:@"%K>%d", _weightProperty, 0]];
request.sortDescriptors = @[ [[NSSortDescriptor alloc] initWithKey:_weightProperty ascending:NO] ];
_fetchedResultsController = [[NSFetchedResultsController alloc]
initWithFetchRequest:request
managedObjectContext:[[MagicalRecordStack defaultStack] context]
sectionNameKeyPath:nil
cacheName:nil];
self.fetchedResultsController.delegate = self;
[_fetchedResultsController MR_performFetch];
偶尔会提取通过[MagicalRecord saveWithBlock:]
进行的保存,但大多数情况下,NSManagedObjectContextWillSaveNotification
仅用于后台上下文,FRC 就在那里:
====>> context will save: saveWithBlock:completion: on *** BACKGROUND THREAD ***
在这种情况下,FRC 永远不会收到通知,并且其代表的 controllerWillUpdateContent
永远不会被解雇。
我觉得这可能是一个简单的问题——最好打电话给 Saul! ;) 任何帮助表示赞赏。
【问题讨论】:
【参考方案1】:如果您的保存最终到达默认上下文,那么您的获取结果控制器最终将重新加载最新信息。可能是 ClassicWithBackgroundCoordinatorMagicalRecordStack 未正确设置为通过该堆栈的“上下文”属性进行保存。
【讨论】:
谢谢。如果我在 FRC 上强制执行 MR_perform_fetch(例如,在 viewWillAppear 中),则更改会被拾取,因此更新将进入默认上下文。他们只是没有立即被 FRC 接走。关于我可以尝试什么的任何建议? 我认为我的问题可能是这个(未能更新具有谓词的 NSFetchedResultsController):***.com/questions/3923826/… 答案表明触发[object willAccessValueForKey:nil]
会有所帮助,但我不清楚是否应该这样做背景上下文(在合并之前)或者如果我需要以某种方式在默认上下文上执行它。感谢您的任何见解。
我想通了(我想)。交易是,当在后台 PSC 中更新值时,需要戳主上下文以查看对象更改。最简单的方法是通过 URI->ObjectID->Object 在主对象存储中查找值,然后在 [MagicalRecord save] 块内对它们运行[willAccessValueForKey:nil]
。这可能需要考虑在 MR 中添加支持,因为它似乎是一个常见的用例。【参考方案2】:
我想我明白了。
当在后台 PSC 中更新值时,需要戳主上下文以查看对象更改。最简单的方法是通过 URI->ObjectID->Object 在主对象存储中查找值,然后在 [MagicalRecord save] 块内对它们运行 [willAccessValueForKey:nil]。这样,当更改合并到主上下文中时,他们就会知道自己出错了,即使来自后台 PSC 的更新只是更改。
【讨论】:
还是这样吗?我似乎遇到了一些非常相似的事情,但是调用 [willAccessValueForKey:nil] 不会向我的 FRC 发送更改通知。以上是关于如何确保在使用 MagicalRecord 3.0 保存后台线程后通知 NSFetchedResultsController的主要内容,如果未能解决你的问题,请参考以下文章
MagicalRecord 2.3.0/3.0 在对象内保存对象
MagicalRecord 3.0 不保存。第二次构建没有对象