【问题标题】:Is AFNetworking with CoreData thread-safe?带有 CoreData 的 AFNetworking 是线程安全的吗?
【发布时间】:2012-11-21 02:33:46
【问题描述】:

我的 iPhone 应用程序遇到间歇性的、难以重现的错误,因此我正在检查我对并发性的假设。

运行 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 会为我提供冲突保护,但崩溃仍然存在(尽管是间歇性的)。

【问题讨论】:

    标签: iphone ios core-data afnetworking


    【解决方案1】:

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

    来自苹果:

    添加到此队列的任务在主线程本身上连续执行。因此,您可以将此队列用作应用程序其他部分中正在完成的工作的同步点。

    在使用多线程 CoreData 和多个托管对象上下文时仍有许多注意事项,对于那些我将您推荐给 rsswtmr's excellent answer,它不能正确回答我的问题,但提供了指向许多有用信息的链接。

    【讨论】:

      【解决方案2】:

      您不能让多个线程在同一个对象上下文上工作。想一想 Core Data 如何在更改/提交数据的过程中参与其中,而另一个更改来自另一个线程。您需要为每个线程创建一个单独的上下文,并在安全/适当时合并更改。 NSOverwriteMergePolicy 将使您不必在合并时手动处理冲突。

      查看here,了解线程核心数据访问的精彩说明。

      【讨论】:

      • 但是 AFNetworking 的回调块没有在主线程上被调用吗?来自 AFHTTPRequestOperation:dispatch_async(self.successCallbackQueue ?self.successCallbackQueue : dispatch_get_main_queue(), ^{ success(self, self.responseData); });
      • 在任何情况下,无论是否是主线程,您都无法保证异步调用何时会在您的代码甚至 Core Data 工作时放弃更改。在每次异步调用之后,你什么时候保存上下文?当您可以保证数据的原子性时,最好将更改累积到单独的上下文中并将它们合并到主线程(同步)。我之前曾多次遇到过这个问题,这很让人抓狂,因为崩溃是不可预测的。单独的上下文似乎为我解决了这个问题。
      • 我认为这是我误解的症结所在,并且希望得到具体确认:即使 AFNetworking 的成功块是在主线程上执行的,如果我要去的话要使用 Core Data,我必须将这些块中的 ManagedObjectContext 视为处于多线程环境中。 @rsswtmr,你有任何链接可以证实这一点吗?
      • 试试thisthis。至少有一个人认为这个问题足够复杂,可以为此专门编写一个名为 AFIncrementalStore 的库。
      • 这些示例仍然基于多线程。我正在继续研究这个,Apple 对主队列这样说:“添加到这个队列的任务是在主线程本身上连续执行的。因此,你可以使用这个队列作为其他部分正在完成的工作的同步点你的申请。”这表明 AFNetworking 的回调被串行添加到主队列中。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-12
      • 2015-04-18
      • 2011-10-07
      • 2012-03-02
      • 2011-10-28
      • 2023-03-14
      相关资源
      最近更新 更多