从后台线程合并更新后,NSFetchedResultsController 不触发委托方法
我有一个 NSFetchedResultsController 和一些通过 NSOperationQueue 在单独线程上插入和更新托管对象的操作。
FRC 看起来像这样,请注意,我已将缓存设置为 nil:
[NSFetchedResultsController deleteCacheWithName:nil];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil];
每个线程操作都有自己的托管对象上下文,并在每次保存更改时向主 MOC 触发 mergeChangesFromContextDidSaveNotification。
我用来合并上下文的代码如下所示:
- (void)mergeContextChanges:(NSNotification *)notification
{
NSManagedObjectContext *context = [fetchedResultsController managedObjectContext];
if([NSThread isMainThread] == NO)
{
[self performSelectorOnMainThread:_cmd withObject:notification waitUntilDone:NO];
return;
}
NSSet *updated = [[notification userInfo] objectForKey:NSUpdatedObjectsKey];
for(NSManagedObject *thing in updated)
{
NSLog(@"Background thread updated %@", [thing description]);
}
for(NSManagedObject *thing in updated)
{
[[context objectWithID:[thing objectID]] willAccessValueForKey:nil];
}
[context mergeChangesFromContextDidSaveNotification:notification];
}
我可以通过查看日志来确认每次后台操作插入或更新数据时,都会使用正确的插入/更新值调用我的 mergeContextChanges: 方法。
问题是,虽然合并插入正确地触发了 FRC 委托方法(例如,controllerDidChangeContent:),但合并更新并没有向 FRC 发出信号来触发其委托方法。
奇怪的是,如果我使用主 MOC 在主线程上运行更新,我还可以确认 FRC 会正确触发其委托。
当更新的 MOC 合并时,如何使 FRC 触发其委托方法?
更多信息:看起来使用除主 MOC 之外的任何 MOC 并尝试将更新合并到主 MOC 会产生相同的结果; FRC拒绝注意到这一点。
I have an NSFetchedResultsController and a few operations that inserts and updates managed objects on separate threads via NSOperationQueue.
The FRC looks like this, note that I have set the cache to nil:
[NSFetchedResultsController deleteCacheWithName:nil];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil];
Each threaded operation has its own managed object context and fires mergeChangesFromContextDidSaveNotification to the main MOC each time it saves changes.
The code that I use to merge contexts looks like this:
- (void)mergeContextChanges:(NSNotification *)notification
{
NSManagedObjectContext *context = [fetchedResultsController managedObjectContext];
if([NSThread isMainThread] == NO)
{
[self performSelectorOnMainThread:_cmd withObject:notification waitUntilDone:NO];
return;
}
NSSet *updated = [[notification userInfo] objectForKey:NSUpdatedObjectsKey];
for(NSManagedObject *thing in updated)
{
NSLog(@"Background thread updated %@", [thing description]);
}
for(NSManagedObject *thing in updated)
{
[[context objectWithID:[thing objectID]] willAccessValueForKey:nil];
}
[context mergeChangesFromContextDidSaveNotification:notification];
}
I can confirm by looking at the logs that each time the background operations insert or update data, my mergeContextChanges: method is being called with the proper insert/update values.
The problem is that while merging inserts are firing the FRCs delegate methods (ex. controllerDidChangeContent:) properly, merging updates doesn't signal the FRC to fire its delegate methods.
Strange enough, I can also confirm that the FRC fires its delegates properly if I run the updates on the main thread using the main MOC.
How can I make the FRC fire its delegate methods when updated MOCs are merged?
More Info: Looks like using any MOC other than the main MOC and trying to merge updates to the main MOC has the same results; the FRC refuses to notice it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
哦……伙计。
看起来从我的线程操作中访问主 MOC(即使它是与我试图更新的数据无关的任务)会导致这种奇怪的行为。
我希望这对遇到此问题的其他人有所帮助。
Oh..... man.
It looks like accessing the main MOC from within my threaded operations (even if it's for a task unrelated to the data I was trying to update) causes this weird behavior.
I hope this helps anyone else that runs into this problem.