将 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
请记住,保存只会将更改“推送”到主上下文。您仍然必须将它们保存到持久存储中。主上下文应该自动知道任何更改(通过NSFetchedResultsControllerDelegate
或NSNotificationCenter
)。
我的数据管理器类(或应用程序委托)中有一个额外的便利方法,用于将数据保存到持久存储中,类似于 Apple 模板提供的普通香草 saveContext
方法。这应该是一个可以在任何地方安全调用的方法,也可以使用上面的块 API 来保存上下文。
【讨论】:
以上是关于将 NSManagedObject(在主上下文中创建)从后台线程传递到主线程是不是安全?的主要内容,如果未能解决你的问题,请参考以下文章
获取 NSManagedObject 的属性作为 NSDictionary
将 NSManagedObject 的关系更改为不同的上下文