1

我正在使用GCD启动一个创建NSManagedObjectContext('MOC')的长时间运行的后台进程('run_loop'),监视CoreData对象,有时(准备好的时候)将它们的序列化上传到一个web服务器然后删除它们。CoreData与GCD队列中的AFNetworking请求不兼容?

我正在使用AFNetworking进行HTTP调用。问题在于请求完成处理程序块中,因为这些块在与MOC的所有者不同的线程中运行,而CoreData不支持该线程。

我已经尝试从GCD run_loop块的开始存储NSThread,并使用performSelector:onThread:run_thread,但这似乎并没有真正调用选择器。

我试过使用dispatch_sync(run_queue),但是这并不能保证线程是一样的,只有GCD队列。主线程中保存的另一个MOC稍后挂起。

最终,唯一有效的工作是在完成回调处理程序中设置布尔值,并引入额外的逻辑来检测布尔开关并从主run_loop执行MOC工作。

任何人都可以建议一个更优雅的修复?或者CoreData与从GCD队列启动的AFNetworking请求不兼容,我应该从头看一下低级别的线程控制?

回答

0

嗯..处理MOC和线程的推荐方法是始终创建一个新的MOC,它是主线程MOC的子moc。让主线程完成所有的保存,但是你的GCD线程基本上可以将更改合并到主MOC中。

我和https://github.com/magicalpanda/MagicalRecord/一起工作得非常成功,以更简单的方式促进这一点。

+0

谢谢!我现在在完成队列中创建第二个MOC,每次调用它时,我都按照http://stackoverflow.com/questions/6959225/core-data-merge-two-managed-object中所述设置了合并-context - 这很好用! – cachvico 2012-07-11 08:58:58

+0

它有效,但它对我来说仍然不太合理。我在一个调度队列上创建了主MOC,因此使用[moc performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification)]看起来不是正确的(当然,mergeChanges ..调用应该在后台线程而不是主线程上运行? )我试着将它切换到[moc performSelector:onThread:run_thread,但这也不起作用,它只是挂起。 – cachvico 2012-07-11 16:34:24

+0

GCD是一个奇怪的野兽,取决于需要什么,你的块可以在任何地方运行,同步分派块实际上在主线程上运行,异步块在任何可用线程上运行。你实际上必须在处理回调或调度的任何地方使用临时MOC。 – piotrb 2012-07-26 22:33:44