diff --git a/Sources/Internal/NSManagedObjectContext+Setup.swift b/Sources/Internal/NSManagedObjectContext+Setup.swift index 854eb0b..bda3c70 100644 --- a/Sources/Internal/NSManagedObjectContext+Setup.swift +++ b/Sources/Internal/NSManagedObjectContext+Setup.swift @@ -100,14 +100,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/Sources/Internal/NSManagedObjectContext+Transaction.swift b/Sources/Internal/NSManagedObjectContext+Transaction.swift index 89cb583..c460652 100644 --- a/Sources/Internal/NSManagedObjectContext+Transaction.swift +++ b/Sources/Internal/NSManagedObjectContext+Transaction.swift @@ -56,6 +56,27 @@ internal extension NSManagedObjectContext { } } + @nonobjc + 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 + ) + } + } + @nonobjc internal func isRunningInAllowedQueue() -> Bool { @@ -93,7 +114,9 @@ internal extension NSManagedObjectContext { do { + self.isSavingSynchronously = true try self.save() + self.isSavingSynchronously = nil } catch { @@ -142,7 +165,9 @@ internal extension NSManagedObjectContext { do { + self.isSavingSynchronously = false try self.save() + self.isSavingSynchronously = nil } catch { @@ -173,7 +198,7 @@ internal extension NSManagedObjectContext { } @nonobjc - internal func refreshAllObjectsAsFaults() { + internal func refreshAndMergeAllObjects() { if #available(iOS 8.3, OSX 10.11, *) { @@ -181,7 +206,7 @@ internal extension NSManagedObjectContext { } else { - self.registeredObjects.forEach { self.refreshObject($0, mergeChanges: false) } + self.registeredObjects.forEach { self.refreshObject($0, mergeChanges: true) } } } @@ -191,5 +216,6 @@ internal extension NSManagedObjectContext { private struct PropertyKeys { static var parentTransaction: Void? + static var isSavingSynchronously: Void? } } diff --git a/Sources/Transactions/BaseDataTransaction.swift b/Sources/Transactions/BaseDataTransaction.swift index 0b8f623..b4562fd 100644 --- a/Sources/Transactions/BaseDataTransaction.swift +++ b/Sources/Transactions/BaseDataTransaction.swift @@ -191,14 +191,14 @@ public /*abstract*/ class BaseDataTransaction { /** Refreshes all registered objects `NSManagedObject`s in the transaction. */ - public func refreshAllObjectsAsFaults() { + public func refreshAndMergeAllObjects() { CoreStore.assert( self.isRunningInAllowedQueue(), "Attempted to refresh entities outside their designated queue." ) - self.context.refreshAllObjectsAsFaults() + self.context.refreshAndMergeAllObjects() } diff --git a/Sources/Transactions/CoreStore+Transaction.swift b/Sources/Transactions/CoreStore+Transaction.swift index 167d50e..06a0f2d 100644 --- a/Sources/Transactions/CoreStore+Transaction.swift +++ b/Sources/Transactions/CoreStore+Transaction.swift @@ -66,9 +66,9 @@ public extension CoreStore { /** Refreshes all registered objects `NSManagedObject`s in the `defaultStack`. */ - public static func refreshAllObjectsAsFaults() { + public static func refreshAndMergeAllObjects() { - self.defaultStack.refreshAllObjectsAsFaults() + self.defaultStack.refreshAndMergeAllObjects() } diff --git a/Sources/Transactions/DataStack+Transaction.swift b/Sources/Transactions/DataStack+Transaction.swift index 7277180..78e4e8b 100644 --- a/Sources/Transactions/DataStack+Transaction.swift +++ b/Sources/Transactions/DataStack+Transaction.swift @@ -83,14 +83,14 @@ public extension DataStack { /** Refreshes all registered objects `NSManagedObject`s in the `DataStack`. */ - public func refreshAllObjectsAsFaults() { + public func refreshAndMergeAllObjects() { CoreStore.assert( NSThread.isMainThread(), "Attempted to refresh entities outside their designated queue." ) - self.mainContext.refreshAllObjectsAsFaults() + self.mainContext.refreshAndMergeAllObjects() }