我无法处理Core Data
并使用Parent/Child context method
处理multithreading with Core Data
。
这是我的应用程序在核心数据和多线程方面的流程:
NSManagedObject
类(仍在bg线程中)Child Context
(仍然在bg线程中),并设置Parent Context
performBlock
并保存Child和Parent上下文我收到了错误:
由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'上下文已经有一个协调器;无法取代。
有时我会同时多次调用服务器。这可能是一个相关的问题,因为performBlock
会阻止父上下文在尝试保存时(例如从另一个线程)?
从我到目前为止所读到的关于使用核心数据和多线程的Parent/Child
上下文方法,我已经理解,基本上当你尝试从后台线程保存时,它将阻止当前的子和父上下文并保存更改。但是如果具有不同子上下文的另一个后台线程试图同时保存会发生什么?
同样是旁注,在我的DatabaseManager
类中,我一直在使用父上下文来获取更新请求,使用子上下文来获取更新请求。这会造成问题吗?
这是我用来获取Parent Context
的单个实例的方法:
// In my DatabaseManager class
lazy var parentContext: NSManagedObjectContext? = {
let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate
if let managedObjectContext = appDelegate.managedObjectContext {
return managedObjectContext
}
else {
return nil
}
}()
// In my AppDelegate
lazy var managedObjectContext: NSManagedObjectContext? = {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
let coordinator = self.persistentStoreCoordinator
if coordinator == nil {
return nil
}
var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = coordinator
managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
return managedObjectContext
}()
DatabaseManager类init和saveContext方法:
init(child: NSManagedObjectContext) {
childContext = child
childContext!.parentContext = parentContext
}
func saveContext() {
if parentContext != nil && childContext != nil {
childContext!.performBlock({
var childError: NSError? = nil
if self.childContext!.save(&childError) {
println("Child context saved")
self.parentContext!.performBlock({
var parentError: NSError? = nil
if self.parentContext!.save(&parentError) {
println("Parent context saved")
}
else {
println("Parent context saving error: \(parentError?.localizedDescription)")
}
})
}
else {
println("Child context saving error: \(childError?.localizedDescription)")
}
})
}
}
在我的HttpResponseManager中创建子上下文,处理来自服务器调用的响应
class HttpResponseManager {
let db: DatabaseManager?
lazy var parentContext: NSManagedObjectContext? = {
let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate
if let managedObjectContext = appDelegate.managedObjectContext {
return managedObjectContext
}
else {
return nil
}
}()
let childContext: NSManagedObjectContext?
init() {
childContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
childContext!.parentContext = parentContext
db = DatabaseManager(child: childContext!)
}
func handleGameInfo(json: JSON) {
let arr = JSON(json[GlobalVars.kEventGameInfoGet].arrayObject!)
for (index: String, obj: JSON) in arr {
var game = NSEntityDescription.insertNewObjectForEntityForName("Game", inManagedObjectContext: self.childContext!) as Game
game.id = obj[GlobalVars.kId].stringValue
game.name = obj[GlobalVars.kName].stringValue
game.platform = obj[GlobalVars.kPlatform].stringValue
game.genre = obj[GlobalVars.kGenre].stringValue
game.coverPhoto = (obj[GlobalVars.kCoverPhoto].arrayValue)[0].stringValue
if db != nil {
db!.updateGame(game)
}
}
}
}