我有一个 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];
}
记录通知的描述可以验证更改是否正确执行。
我的问题
未调用 NSFetchedResultsControllerDelegate 的委托(delegate)方法。
这很奇怪,因为处理相同的上下文,即主要上下文,允许监听更改并调用委托(delegate)方法,例如在 UITableView 中删除一个行对象。
我在 SO 上发现了一些具有相同问题的主题。我已经尝试了所有解决方法,但找不到有值(value)的解决方案:
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];
现在,关于 Jody 最后的评论
In the main() of your NSOperation, you are loading new objects, and in there it looks like you are setting isSync to YES for each new object. The predicate you use for the fetchedResultsController is looking only for objects that have isSync == NO.
我希望当属性 isSync 设置为 YES 时,NSFetchedResultsController 会观察到更改并删除与谓词不匹配的行。我错了吗?
请记住,当将更改从后台合并到主线程时,我能够看到很少有对象更新了它们的 isSync 属性。
最佳答案
你有基本的想法,所以你的代码中某处可能存在错误...
仔细检查您是否正确注册以接收来自后台 MOC 的通知。
注册以接收来自所有对象的所有通知。在该方法中,记录事件及其所有数据。当对象是 MOC 时,转储其所有属性(尤其是注册、插入、更新和删除对象的列表)。
在保存调用之前和之后放置一条日志语句,并在通知处理程序中用于合并通知。
此外,您省略了很多代码,因此很难知道您实际在做什么,但您包含的代码示例看起来很难将所有正在加载的对象的 isSync 设置为 YES,但您的获取请求只需要那些isSync 设置为 NO。这些新对象都不会通过该谓词。
最后,仔细检查您的模型定义并确保您使用的是正确的数字类型。这可能是问题的一大根源。
编辑
哦,是的,我忘了...您的提取请求没有排序描述符。当您创建 FRC 时,您的获取请求必须包含至少一个排序描述符...如果您有多个部分,第一个排序描述符用于将对象分组到部分中。
跟进 Alexsander 的评论...我在帖子的开头提到了它,但你肯定不想听来自 MOC 的通知,除非它是你的一个众所周知的(除非,当然,您只是为了调试目的而记录)。您应该了解您正在使用的 MOC。
此外,我建议使用父/子 MOC 进行此类处理,但如果操作得当,您所做的应该会起作用。
Parent(私有(private)并发类型) Main(主并发类型)
然后,对于您的背景 MOC,只需让它们将主 moc 设置为其父级即可。当他们保存时,他们的对象会直接注入(inject)到主 MOC 中。然后主 MOC 可以在稍后发布保存以将它们放到磁盘上。
或者,您可以将后台 MOC 设置为“父级”,然后“主要”MOC 可以重新发出提取以从父级获取数据。
关于ios - NSFetchedResultsController 不显示来自不同上下文的更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10428271/
我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择
我试图在索引页中创建一个超链接,但它没有显示,也没有给出任何错误。这是我的index.html.erb代码。ListingarticlesTitleTextssss我检查了我的路线,我认为它们也没有问题。PrefixVerbURIPatternController#Actionwelcome_indexGET/welcome/index(.:format)welcome#indexarticlesGET/articles(.:format)articles#indexPOST/articles(.:format)articles#createnew_articleGET/article
我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的
目前,Itembelongs_toCompany和has_manyItemVariants。我正在尝试使用嵌套的fields_for通过Item表单添加ItemVariant字段,但是使用:item_variants不显示该表单。只有当我使用单数时才会显示。我检查了我的关联,它们似乎是正确的,这可能与嵌套在公司下的项目有关,还是我遗漏了其他东西?提前致谢。注意:下面的代码片段中省略了不相关的代码。编辑:不知道这是否相关,但我正在使用CanCan进行身份验证。routes.rbresources:companiesdoresources:itemsenditem.rbclassItemi
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
如果我在模型中设置验证消息validates:name,:presence=>{:message=>'Thenamecantbeblank.'}我如何让该消息显示在闪光警报中,这是我迄今为止尝试过的方法defcreate@message=Message.new(params[:message])if@message.valid?ContactMailer.send_mail(@message).deliverredirect_to(root_path,:notice=>"Thanksforyourmessage,Iwillbeintouchsoon")elseflash[:error]