Lor*_*o B 22 core-data nsfetchedresultscontroller nsoperationqueue nsmanagedobjectcontext ios
我有一个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;
}
Run Code Online (Sandbox Code Playgroud)
主线程和线程操作具有自己的托管对象上下文.他们只共享同一个协调员.
在线程操作中,我将isSync属性从更改NO为YES.要知道Check要更新的实体是什么,主要上下文将传递给线程化的a 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;
}
Run Code Online (Sandbox Code Playgroud)
当线程操作调用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];
}
Run Code Online (Sandbox Code Playgroud)
记录notification潜在客户的描述以验证是否正确执行了更改.
我的问题
代理方法NSFetchedResultsControllerDelegate没有被调用.
这很奇怪,因为处理相同的上下文,主要的,允许侦听更改和委托方法被调用,例如删除行中的对象UITableView.
我在SO上找到了一些有同样问题的主题.我已经尝试了所有的解决方法,但我找不到有价值的解决方案:
先感谢您.
编辑
上面的代码在之前的模型中工作.然后我创建了一个新模型复制(和粘贴)前一个实体,现在它不再工作了.
建议?
编辑2
这是我在NSFetchedResultsControllergetter中使用的谓词.这是我的错,但是当我写这篇文章时,我没有复制它.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"insertionDate" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
// previous code here
[fetchRequest setSortDescriptors:sortDescriptors];
Run Code Online (Sandbox Code Playgroud)
现在,关于Jody的最后评论
在NSOperation的main()中,您正在加载新对象,并且在那里看起来您正在为每个新对象将isSync设置为YES.您用于fetchedResultsController的谓词仅查找具有isSync == NO的对象.
我希望当属性isSync设置为YES时,NSFetchedResultsController观察到更改并删除与谓词不匹配的行.我错了吗?
请记住,当将更改从背景合并到主线程时,我能够看到很少有对象更新了它们的isSync属性.
Jod*_*ins 11
你有基本的想法,所以你的代码中可能存在一个错误......
仔细检查您是否正确注册以接收来自后台MOC的通知.
注册以接收来自所有对象的所有通知.在该方法中,记录事件及其所有数据.当对象是MOC时,转储其所有属性(尤其是已注册,已插入,已更新和已删除对象的列表).
在保存调用之前和之后放置一个日志语句,并在通知处理程序中合并通知.
此外,您省略了很多代码,因此很难知道您实际在做什么,但是您包含的代码示例看起来很难将所有正在加载的对象的isSync设置为YES,但是您的获取请求只需要设置了isSync的那些没有.这些新对象都不会传递该谓词.
最后,仔细检查您的模型定义并确保使用正确的数字类型.这可能是问题的重要来源.
编辑
哦是的,我忘了...你的获取请求没有排序描述符.创建FRC时,您的获取请求必须至少包含一个排序描述符...如果您有多个部分,则使用第一个排序描述符将对象分组为多个部分.
跟进Alexsander的评论......我在帖子的开头提到了它,但是你肯定不想听MOC的通知,除非它是众所周知的(当然,除非你是只是记录以进行调试).您应该了解您正在使用的MOC.
此外,我建议使用父/子MOC进行此类处理,但如果操作正确,您正在做的事情应该有效.
父(私有并发类型)Main(主并发类型)
然后,使用您的背景MOC,让他们将主moc设置为其父级.当他们保存时,他们的对象被直接注入主MOC.然后,主MOC可以在以后发出保存以将它们放到磁盘上.
或者,您可以将背景MOC作为"父"的父级,然后"主"MOC可以重新发出获取以从父级获取数据.
| 归档时间: |
|
| 查看次数: |
9671 次 |
| 最近记录: |