From 26ae6293cabf2b9230efae86a3bcd07b7bfc4dde Mon Sep 17 00:00:00 2001 From: John Rommel Estropia Date: Sat, 7 May 2016 12:18:54 +0800 Subject: [PATCH] merge changes to main context synchronously or asynchronously depending on the caller intention (fixes #65) --- .../NSManagedObjectContext+Setup.swift | 20 ++++++++++++--- .../NSManagedObjectContext+Transaction.swift | 25 +++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/CoreStore/Internal/NSManagedObjectContext+Setup.swift b/CoreStore/Internal/NSManagedObjectContext+Setup.swift index 6a06676..4438c74 100644 --- a/CoreStore/Internal/NSManagedObjectContext+Setup.swift +++ b/CoreStore/Internal/NSManagedObjectContext+Setup.swift @@ -82,14 +82,28 @@ internal extension NSManagedObjectContext { object: rootContext, closure: { [weak context] (note) -> Void in - context?.performBlock { () -> Void in + guard let rootContext = note.object as? NSManagedObjectContext, + let context = context else { + + return + } + let mergeChanges = { () -> Void in let updatedObjects = (note.userInfo?[NSUpdatedObjectsKey] as? Set) ?? [] for object in updatedObjects { - context?.objectWithID(object.objectID).willAccessValueForKey(nil) + context.objectWithID(object.objectID).willAccessValueForKey(nil) } - context?.mergeChangesFromContextDidSaveNotification(note) + context.mergeChangesFromContextDidSaveNotification(note) + } + + if rootContext.isSavingSynchronously == true { + + context.performBlockAndWait(mergeChanges) + } + else { + + context.performBlock(mergeChanges) } } ) diff --git a/CoreStore/Internal/NSManagedObjectContext+Transaction.swift b/CoreStore/Internal/NSManagedObjectContext+Transaction.swift index 8a911a1..9415689 100644 --- a/CoreStore/Internal/NSManagedObjectContext+Transaction.swift +++ b/CoreStore/Internal/NSManagedObjectContext+Transaction.swift @@ -55,6 +55,26 @@ internal extension NSManagedObjectContext { } } + internal var isSavingSynchronously: Bool? { + + get { + + let value: NSNumber? = getAssociatedObjectForKey( + &PropertyKeys.isSavingSynchronously, + inObject: self + ) + return value?.boolValue + } + set { + + setAssociatedWeakObject( + newValue.flatMap { NSNumber(bool: $0) }, + forKey: &PropertyKeys.isSavingSynchronously, + inObject: self + ) + } + } + internal func isRunningInAllowedQueue() -> Bool { guard let parentTransaction = self.parentTransaction else { @@ -89,7 +109,9 @@ internal extension NSManagedObjectContext { do { + self.isSavingSynchronously = true try self.save() + self.isSavingSynchronously = nil } catch { @@ -137,7 +159,9 @@ internal extension NSManagedObjectContext { do { + self.isSavingSynchronously = false try self.save() + self.isSavingSynchronously = nil } catch { @@ -185,5 +209,6 @@ internal extension NSManagedObjectContext { private struct PropertyKeys { static var parentTransaction: Void? + static var isSavingSynchronously: Void? } }