【发布时间】:2012-05-12 18:49:50
【问题描述】:
我有一个NSFetchedResultsController 和一些操作通过NSOperationQueue 更新不同线程上的托管对象。
FRC(及其谓词)如下所示:
- (NSFetchedResultsController*)fetchedResultsController
{
if(fetchedResultsController) return fetchedResultsController;
NSManagedObjectContext* mainContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Check" inManagedObjectContext:mainContext]];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"isSync == %@", [NSNumber numberWithBool:NO]]];
[fetchRequest setFetchBatchSize:10];
fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:mainContext sectionNameKeyPath:nil cacheName:nil];
fetchedResultsController.delegate = self;
[fetchRequest release], fetchRequest = nil;
return fetchedResultsController;
}
主线程和线程操作都有自己的托管对象上下文。他们只共享同一个协调器。
在线程操作中,我将isSync 属性从NO 更改为YES。要知道要更新的Check 实体是什么,主上下文将传递给线程一个NSManagedObjectID。
线程操作检索托管对象,如下所示:
-(void)main
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSManagedObjectContext *exportContext = [[NSManagedObjectContext alloc] init];
[exportContext setPersistentStoreCoordinator:[self persistentStoreCoordinator]];
//...
Check* check = (Check*)[exportContext existingObjectWithID:objID error:&error];
check.isSync = [NSNumber numberWithBool:YES];
//...
[exportContext save:&error];
[pool release], pool = nil;
}
当线程操作调用save 时,会调用mergeChangesFromContextDidSaveNotification 通知并且主上下文合并更改。
- (void)contextChanged:(NSNotification*)notification
{
if ([notification object] == [self managedObjectContext]) return;
if (![NSThread isMainThread]) {
[self performSelectorOnMainThread:@selector(contextChanged:) withObject:notification waitUntilDone:YES];
return;
}
[[self managedObjectContext] mergeChangesFromContextDidSaveNotification:notification];
}
记录notification 的描述可以验证更改是否正确执行。
我的问题
NSFetchedResultsControllerDelegate 的委托方法不会被调用。
这很奇怪,因为处理相同的上下文(主要的上下文)允许监听更改并调用委托方法,例如删除UITableView中的一个行对象。
我发现一些关于 SO 的主题存在同样的问题。我已经尝试了所有解决方法,但找不到有价值的解决方案:
NSFetchedResultsController not showing updates from other contexts
NSFetchedResultsController not firing delegate method after merging update from background thread
提前谢谢你。
编辑
上面的代码在以前的模型中工作。然后我创建了一个新模型,从前一个模型中复制(和粘贴)实体,现在它不再工作了。
建议?
编辑 2
这是我在NSFetchedResultsController getter 中使用的谓词。是我的错,但是我写的时候没有抄。
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"insertionDate" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
// previous code here
[fetchRequest setSortDescriptors:sortDescriptors];
现在,关于乔迪最后的评论
在您的 NSOperation 的 main() 中,您正在加载新对象,并且在 看起来你正在为每个新对象设置 isSync 为 YES 。 您用于 fetchedResultsController 的谓词仅查看 对于具有 isSync == NO 的对象。
我希望当属性 isSync 设置为 YES 时,NSFetchedResultsController 会观察到更改并删除与谓词不匹配的行。我错了吗?
请记住,当将更改从后台合并到主线程时,我可以看到很少有对象更新了它们的 isSync 属性。
【问题讨论】:
-
查看我对这个问题的回答。我认为这可能会有所帮助:stackoverflow.com/questions/3923826/…
-
通过阅读您的问题,我认为@ArturFriesen 是正确的:NSFetchedResultsController 忽略了发生在它自己或其子上下文之外的更改。您需要在主 moc 中的每个相关对象上调用 refreshObject。另一种方法:stackoverflow.com/a/21378533/313633
标签: ios core-data nsfetchedresultscontroller nsmanagedobjectcontext nsoperationqueue