From e64fc3d2d86ab4d87d922a4f5f539396b93c21b0 Mon Sep 17 00:00:00 2001 From: John Rommel Estropia Date: Thu, 5 Mar 2015 21:31:38 +0800 Subject: [PATCH] changed concurrency architecture. Transactions are now done on a direct child context of the root saving context (instead of a main context child) --- HardcoreData/DataStack+Transaction.swift | 4 ++-- HardcoreData/DataStack.swift | 19 +++++++++++++------ .../NSManagedObject+Transaction.swift | 10 +++++++++- .../NSManagedObjectContext+Transaction.swift | 2 +- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/HardcoreData/DataStack+Transaction.swift b/HardcoreData/DataStack+Transaction.swift index 303fd26..04801f6 100644 --- a/HardcoreData/DataStack+Transaction.swift +++ b/HardcoreData/DataStack+Transaction.swift @@ -41,7 +41,7 @@ public extension DataStack { public func performTransaction(closure: (transaction: AsynchronousDataTransaction) -> Void) { AsynchronousDataTransaction( - mainContext: self.mainContext, + mainContext: self.rootSavingContext, queue: self.childTransactionQueue, closure: closure).perform() } @@ -55,7 +55,7 @@ public extension DataStack { public func performTransactionAndWait(closure: (transaction: SynchronousDataTransaction) -> Void) -> SaveResult? { return SynchronousDataTransaction( - mainContext: self.mainContext, + mainContext: self.rootSavingContext, queue: self.childTransactionQueue, closure: closure).performAndWait() } diff --git a/HardcoreData/DataStack.swift b/HardcoreData/DataStack.swift index e50f19d..a92bddb 100644 --- a/HardcoreData/DataStack.swift +++ b/HardcoreData/DataStack.swift @@ -45,11 +45,14 @@ public class DataStack { // MARK: Public /** - Initializes a DataStack from merged model in the app bundle. + Initializes a DataStack from a model created by merging all the models found in all bundles. */ public convenience init() { - self.init(managedObjectModel: NSManagedObjectModel.mergedModelFromBundles(NSBundle.allBundles())!) + let mergedModel: NSManagedObjectModel! = NSManagedObjectModel.mergedModelFromBundles(NSBundle.allBundles()) + HardcoreData.assert(mergedModel != nil, "Could not create a merged <\(NSManagedObjectModel.self)> from all bundles.") + + self.init(managedObjectModel: mergedModel) } /** @@ -59,8 +62,11 @@ public class DataStack { */ public convenience init(modelName: String) { - let modelFilePath = NSBundle.mainBundle().pathForResource(modelName, ofType: "momd")! - let managedObjectModel = NSManagedObjectModel(contentsOfURL: NSURL(fileURLWithPath: modelFilePath)!)! + let modelFilePath: String! = NSBundle.mainBundle().pathForResource(modelName, ofType: "momd") + HardcoreData.assert(modelFilePath != nil, "Could not find a \"momd\" resource from the main bundle.") + + let managedObjectModel: NSManagedObjectModel! = NSManagedObjectModel(contentsOfURL: NSURL(fileURLWithPath: modelFilePath)!) + HardcoreData.assert(managedObjectModel != nil, "Could not create an <\(NSManagedObjectModel.self)> from the resource at path \"\(modelFilePath)\".") self.init(managedObjectModel: managedObjectModel) } @@ -218,7 +224,8 @@ public class DataStack { where ( resetStoreOnMigrationFailure && (error.code == NSPersistentStoreIncompatibleVersionHashError - || error.code == NSMigrationMissingSourceModelError) + || error.code == NSMigrationMissingSourceModelError + || error.code == NSMigrationError) && error.domain == NSCocoaErrorDomain ) { @@ -259,6 +266,7 @@ public class DataStack { // MARK: Internal + internal let rootSavingContext: NSManagedObjectContext internal let mainContext: NSManagedObjectContext internal let childTransactionQueue: GCDQueue = .createSerial("com.hardcoredata.datastack.childtransactionqueue") @@ -274,6 +282,5 @@ public class DataStack { private typealias EntityNameType = String private let coordinator: NSPersistentStoreCoordinator - private let rootSavingContext: NSManagedObjectContext private let entityNameMapping: [EntityClassNameType: EntityNameType] } diff --git a/HardcoreData/NSManagedObject+Transaction.swift b/HardcoreData/NSManagedObject+Transaction.swift index ddfd16d..e306105 100644 --- a/HardcoreData/NSManagedObject+Transaction.swift +++ b/HardcoreData/NSManagedObject+Transaction.swift @@ -60,7 +60,15 @@ internal extension NSManagedObject { if objectID.temporaryID { var error: NSError? - if !context.obtainPermanentIDsForObjects([self], error: &error) { + var didSucceed: Bool? + if let managedObjectContext = self.managedObjectContext { + + managedObjectContext.performBlockAndWait { + + didSucceed = managedObjectContext.obtainPermanentIDsForObjects([self], error: &error) + } + } + if didSucceed != true { HardcoreData.handleError( error ?? NSError(hardcoreDataErrorCode: .UnknownError), diff --git a/HardcoreData/NSManagedObjectContext+Transaction.swift b/HardcoreData/NSManagedObjectContext+Transaction.swift index 55a1ac7..c287208 100644 --- a/HardcoreData/NSManagedObjectContext+Transaction.swift +++ b/HardcoreData/NSManagedObjectContext+Transaction.swift @@ -54,7 +54,7 @@ internal extension NSManagedObjectContext { context.parentContext = self context.parentStack = self.parentStack context.setupForHardcoreDataWithContextName("com.hardcoredata.temporarycontext") - context.shouldCascadeSavesToParent = (self.concurrencyType == .MainQueueConcurrencyType) + context.shouldCascadeSavesToParent = (self.parentStack?.rootSavingContext == self) return context }