2012-11-21 32 views
2

我在我的iPhone应用程序中遇到了间歇性的,难以重现的错误,因此我正在检查围绕并发的假设。AFNetworking是否与CoreData线程安全?

运行AFNetworking v0.10.x,我有以下网络呼叫:

[self postPath:@"/myEndPoint" 
    parameters:params 
     success:^(AFHTTPRequestOperation *request, id response) 
      { 
       AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate]; 
       // do stuff with object context here 
       [appDelegate.objectContext save]; 
      }  
]  
AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate]; 
// do other stuff with object context 
[appDelegate.objectContext save];  

在我的AppDelegate:

-(NSManagedObjectContext*) objectContext 
{ 
    if(nil == _objectContext) 
    { 
     ... set up sqlite persistent store coordinator and object model ... 

     _objectContext = [[NSManagedObjectContext alloc] init]; 
     [_objectContext setPersistentStoreCoordinator:persistentStoreCoordinator]; 
     [_objectContext setMergePolicy:NSOverwriteMergePolicy]; 
    } 
    return _objectContext; 
} 

是否有可能,在这种情况下,结束了并发问题?或者换句话说,AFNetworking的API是线程安全的?我认为NSOverwriteMergePolicy会掩盖我的冲突,但崩溃持续(尽管间歇性)。

回答

5

AFNetworking的回调在主线程上执行。因此,它们是'线程安全的',因为只有一个与CoreData交互的线程。如果你只有一个管理对象,事情将很简单。

从苹果:

“的任务加入到这一队列的主线程本身串行执行。因此,你可以使用这个队列作为同步点的工作在你的应用程序的其他部分正在做的。”

当使用多线程CoreData和多个托管对象上下文时,仍然有很多注意事项,对于那些我向你推荐rsswtmr的优秀答案,它不能正确回答我的问题,但提供了很多良好信息的链接。

2

您不能有多个线程在同一个对象上下文上工作。考虑一下Core Data如何通过改变/提交数据来部分实现,而在另一个线程上发生另一个改变。您需要为每个线程创建一个单独的上下文,并在安全/合适时合并更改。 NSOverwriteMergePolicy将简单地保存您不必在合并时手动处理冲突。

查看here可以很好地解释线程核心数据访问。

+0

但是AFNetworking的回调块没有在主线程上调用?从AFHTTPRequestOperation:'dispatch_async(self.successCallbackQueue?self.successCallbackQueue:dispatch_get_main_queue(),^ {success(self,self.responseData);});' – meriial

+0

无论如何,主线程与否,调用会在您的代码或核心数据在工作时发生变化。在每次异步调用之后,何时保存上下文?当你可以保证数据的原子性时,你最好将更改累积到单独的上下文中,并将它们合并到主线程(同步)。我之前遇到过这个问题几次,而且它很疯狂,因为崩溃是不可预测的。单独的上下文似乎为我解决了这个问题。 – rsswtmr

+0

我认为这是我误解的症结所在,并希望得到具体的确认:**即使** AFNetworking的成功块在主线程上执行,如果要使用核心数据,我必须将ManagedObjectContext在这些块中,就好像它在多线程环境中一样。 @rsswtmr,你有任何链接可以证实这一点吗? – meriial