将 NSManagedObject(在主上下文中创建)从后台线程传递到主线程是不是安全?

Posted

技术标签:

【中文标题】将 NSManagedObject(在主上下文中创建)从后台线程传递到主线程是不是安全?【英文标题】:Is it safe to pass NSManagedObject(created in main context) from a background thread to the main thread?将 NSManagedObject(在主上下文中创建)从后台线程传递到主线程是否安全? 【发布时间】:2015-09-15 23:42:45 【问题描述】:

我正在使用 AFNetworking 解析一些数据,然后保存到 CoreData,我想做这样的事情。

let parserContext: NSManagedObjectContext = MTCoreDataManager.sharedManager().newPrivateManagedObjectContext()
let mainContext: NSManagedObjectContext = MTCoreDataManager.sharedManager().managedObjectContext()

override func responseObjectForResponse(response: NSURLResponse!, data: NSData!, error: NSErrorPointer) -> AnyObject? 
    var model: NSManagedObject?
    parserContext.performBlockAndWait 
        ....parsing data...
        ....create model and assign value...
        ....save model...
        let objID = model.objectID
        mainContext.performBlockAndWait 
           model = mainContext.objectWithID(objID)
        
    
    return model


let op = AF.GET(path, parameters: nil, success:  (operation: AFHTTPRequestOperation, response: AnyObject) -> Void in
        // main thread
        println(response)
)  (operation: AFHTTPRequestOperation, error: NSError) -> Void in
        println(error.description)

由于 responseObjectForResponse 在后台线程中运行,我想使用后台上下文来解析数据并在该上下文中创建 NSManagedObject,然后在主线程中取回对象,因为最终回调将在主线程上,我不想返回 NSManagedObjectID,我想返回 NSManagedObject 但我不知道这是否安全。

【问题讨论】:

【参考方案1】:

安全吗?我不这么认为。

相反,您应该在完成块中创建一个子上下文,并在一个块中保存所有核心数据。

childContext.performBlockAndWait() 
    // parse, insert and save

请记住,保存只会将更改“推送”到主上下文。您仍然必须将它们保存到持久存储中。主上下文应该自动知道任何更改(通过NSFetchedResultsControllerDelegateNSNotificationCenter)。

我的数据管理器类(或应用程序委托)中有一个额外的便利方法,用于将数据保存到持久存储中,类似于 Apple 模板提供的普通香草 saveContext 方法。这应该是一个可以在任何地方安全调用的方法,也可以使用上面的块 API 来保存上下文。

【讨论】:

以上是关于将 NSManagedObject(在主上下文中创建)从后台线程传递到主线程是不是安全?的主要内容,如果未能解决你的问题,请参考以下文章

NSManagedObject 如何重新加载

获取 NSManagedObject 的属性作为 NSDictionary

将 NSManagedObject 传递给子上下文不起作用

将 NSManagedObject 的关系更改为不同的上下文

如何将 imageData 保存到 NSManagedObject 属性

将 NSManagedObject 重新插入到 ManagedObjectContext