From 0c0a2a382cbf4dfeb3473841a761afc3afd33aa0 Mon Sep 17 00:00:00 2001 From: John Rommel Estropia Date: Sat, 14 Nov 2015 20:00:40 +0900 Subject: [PATCH] Deprecated rollback() on async and sync transactions. Added undo utilities to unsafe transactions. --- CoreStore/Info.plist | 2 +- .../AsynchronousDataTransaction.swift | 14 +++++++---- .../BaseDataTransaction.swift | 15 ------------ .../SynchronousDataTransaction.swift | 12 +++++++--- .../UnsafeDataTransaction.swift | 24 +++++++++++++++++++ 5 files changed, 44 insertions(+), 23 deletions(-) diff --git a/CoreStore/Info.plist b/CoreStore/Info.plist index 009ff7e..2e9a7c2 100644 --- a/CoreStore/Info.plist +++ b/CoreStore/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.3.3 + 1.3.4 CFBundleSignature ???? CFBundleVersion diff --git a/CoreStore/Saving and Processing/AsynchronousDataTransaction.swift b/CoreStore/Saving and Processing/AsynchronousDataTransaction.swift index cddd47f..a486b62 100644 --- a/CoreStore/Saving and Processing/AsynchronousDataTransaction.swift +++ b/CoreStore/Saving and Processing/AsynchronousDataTransaction.swift @@ -190,16 +190,21 @@ public final class AsynchronousDataTransaction: BaseDataTransaction { } /** - Rolls back the transaction by resetting the `NSManagedObjectContext`. After calling this method, all `NSManagedObjects` fetched within the transaction will become invalid. This method should not be used after the `commit()` method was already called once. - */ - public override func rollback() { + Rolls back the transaction by resetting the `NSManagedObjectContext`. After calling this method, all `NSManagedObjects` fetched within the transaction will become invalid. This method should not be used after the `commit()` method was already called once. + */ + @available(*, deprecated=1.3.4, message="Resetting the context is inherently unsafe. This method will be removed in the near future. Use `beginUnsafe()` to create transactions with `undo` support.") + public func rollback() { CoreStore.assert( !self.isCommitted, "Attempted to rollback an already committed \(typeName(self))." ) + CoreStore.assert( + self.transactionQueue.isCurrentExecutionContext(), + "Attempted to rollback a \(typeName(self)) outside its designated queue." + ) - super.rollback() + self.context.reset() } @@ -210,6 +215,7 @@ public final class AsynchronousDataTransaction: BaseDataTransaction { self.closure = closure super.init(mainContext: mainContext, queue: queue) + self.context.undoManager = nil } internal func perform() { diff --git a/CoreStore/Saving and Processing/BaseDataTransaction.swift b/CoreStore/Saving and Processing/BaseDataTransaction.swift index addc74e..0aad856 100644 --- a/CoreStore/Saving and Processing/BaseDataTransaction.swift +++ b/CoreStore/Saving and Processing/BaseDataTransaction.swift @@ -186,21 +186,6 @@ public /*abstract*/ class BaseDataTransaction { objects.forEach { context.fetchExisting($0)?.deleteFromContext() } } - // MARK: Saving changes - - /** - Rolls back the transaction by resetting the `NSManagedObjectContext`. After calling this method, all `NSManagedObjects` fetched within the transaction will become invalid. - */ - public func rollback() { - - CoreStore.assert( - self.bypassesQueueing || self.transactionQueue.isCurrentExecutionContext(), - "Attempted to rollback a \(typeName(self)) outside its designated queue." - ) - - self.context.reset() - } - // MARK: Internal diff --git a/CoreStore/Saving and Processing/SynchronousDataTransaction.swift b/CoreStore/Saving and Processing/SynchronousDataTransaction.swift index 2733320..bace899 100644 --- a/CoreStore/Saving and Processing/SynchronousDataTransaction.swift +++ b/CoreStore/Saving and Processing/SynchronousDataTransaction.swift @@ -181,15 +181,20 @@ public final class SynchronousDataTransaction: BaseDataTransaction { /** Rolls back the transaction by resetting the `NSManagedObjectContext`. After calling this method, all `NSManagedObjects` fetched within the transaction will become invalid. This method should not be used after the `commit()` method was already called once. - */ - public override func rollback() { + */ + @available(*, deprecated=1.3.4, message="Resetting the context is inherently unsafe. This method will be removed in the near future. Use `beginUnsafe()` to create transactions with `undo` support.") + public func rollback() { CoreStore.assert( !self.isCommitted, "Attempted to rollback an already committed \(typeName(self))." ) + CoreStore.assert( + self.transactionQueue.isCurrentExecutionContext(), + "Attempted to rollback a \(typeName(self)) outside its designated queue." + ) - super.rollback() + self.context.reset() } @@ -217,6 +222,7 @@ public final class SynchronousDataTransaction: BaseDataTransaction { self.closure = closure super.init(mainContext: mainContext, queue: queue) + self.context.undoManager = nil } diff --git a/CoreStore/Saving and Processing/UnsafeDataTransaction.swift b/CoreStore/Saving and Processing/UnsafeDataTransaction.swift index 98831ba..4298b01 100644 --- a/CoreStore/Saving and Processing/UnsafeDataTransaction.swift +++ b/CoreStore/Saving and Processing/UnsafeDataTransaction.swift @@ -55,6 +55,30 @@ public final class UnsafeDataTransaction: BaseDataTransaction { } } + /** + Rolls back the transaction. + */ + public func rollback() { + + self.context.rollback() + } + + /** + Undo's the last change made to the transaction. + */ + public func undo() { + + self.context.undo() + } + + /** + Redo's the last undone change to the transaction. + */ + public func redo() { + + self.context.redo() + } + /** Begins a child transaction where `NSManagedObject` creates, updates, and deletes can be made. This is useful for making temporary changes, such as partially filled forms.