CoreData 与来自 GCD 队列的 AFNetworking 请求不兼容?

Posted

技术标签:

【中文标题】CoreData 与来自 GCD 队列的 AFNetworking 请求不兼容?【英文标题】:CoreData not compatible with an AFNetworking request from a GCD queue? 【发布时间】:2012-07-11 08:14:39 【问题描述】:

我正在使用 GCD 启动一个长时间运行的后台进程 ('run_loop'),它创建一个 NSManagedObjectContext ('MOC'),监控 CoreData 对象,有时(当它们准备好时)将它们的序列化上传到网络服务器,然后删除它们。

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

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

我尝试过使用 dispatch_sync(run_queue) 但这不能保证线程是相同的,只有 GCD 队列。稍后在主线程中保存的不同 MOC 挂起。

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

有人能提出更优雅的解决方法吗?还是 CoreData 根本不兼容从 GCD 队列启动的 AFNetworking 请求,我应该从一开始就查看较低级别的线程控制?

【问题讨论】:

【参考方案1】:

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

我与https://github.com/magicalpanda/MagicalRecord/ 合作取得了相当大的成功,以更简单的方式促进了这一点。

【讨论】:

谢谢!我现在在完成队列中创建第二个 MOC,每次调用它时,我都按照***.com/questions/6959225/… 中的描述设置了合并 - 这很好用! 它有效,但对我来说仍然不太有意义;我在调度队列上创建了主 MOC,因此使用 [moc performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification)] 似乎也不正确(当然,mergeChanges .. 调用应该在后台线程上运行,而不是在主线程上运行? ) 我尝试将其切换到 [moc performSelector:onThread:run_thread,但这也不起作用,它只是挂起。 GCD 是一个奇怪的野兽,根据需要,您的块几乎可以在任何地方运行,同步调度的块实际上在主线程上运行,异步的块在任何可用线程上运行。实际上,您基本上必须在处理回调或调度的任何地方使用临时 MOC。

以上是关于CoreData 与来自 GCD 队列的 AFNetworking 请求不兼容?的主要内容,如果未能解决你的问题,请参考以下文章

GCD 中的并发队列与串行队列

来自 2 个串行队列的 NSManagedObjectContext 死锁

ios多线程操作—— GCD串行队列与并发队列

GCD使用 串行并行队列 与 同步异步执行的各种组合 及要点分析

如何通过创建本地上下文将 GCD 与 Core Data 一起使用

iOS中GCD的使用小结