11

I'm instantiating a NSManagedObjectContext object at the Application delegate level and sharing it across all my UIViewControllers. Here's the code that I use to access it in one of my View Controllers:

        NSManagedObjectContext *managedObjectContext = appDelegate.managedObjectContext;
        modelObj = (Model *) [NSEntityDescription insertNewObjectForEntityForName:@"Model" inManagedObjectContext:[appDelegate managedObjectContext]];

Now in this screen, I have a UITableView with 9 rows & each cell has a UITextField. As the user inputs values into the textfields, I assign them into modelObj. Now, my user has an option to cancel out and discard all the changes or save them to disk. I have the save code working fine. But in the case when a user tries to discard the changes, I'm not sure what to do. There doesn't seem to be a [managedObjectContext discardChanges] method to throw them all away.

I can think of a couple of ways of solving this.

  • Create a new instance of NSManagedObjectContext for each controller instead of sharing one across the application.
  • Or, I could create a bunch of NSStrings in my code and save user values in them and call insertNewObjectForEntityForName: only if the user clicks save.

Which way is the right one? Or is there a way to make NSManagedObjectConext discard all the changes that were made to it?

Thanks,
Teja.

Tejaswi Yerukalapudi
  • 8,987
  • 12
  • 60
  • 101
  • 1
    Tim Dean's answer is correct. But it also wouldn't be a wrong approach to create a child context for this edit screen, insert your new object there, and only save it up to the parent context if the user confirms. Otherwise, just throw the child away, and you're done. – Sixten Otto Sep 18 '13 at 21:58

3 Answers3

43

NSManagedObjectContext has a simple method for this:

[managedObjectContext rollback];

This method "removes everything from the undo stack, discards all insertions and deletions, and restores updated objects to their last committed values." (documentation)

Unless I'm missing something, that should give you everything you need.

Daniel Hawkins
  • 1,165
  • 13
  • 12
Tim Dean
  • 8,253
  • 2
  • 32
  • 59
  • 3
    Since the question is tagged with iOS it might be useful to mention that the rollback method requires that an `undoManager` is assigned to the MOC, which in the case of iOS I believe it is not by default and so `rollback` will do nothing. – Christopher King May 13 '15 at 18:19
  • 1
    Here is the reference supporting @ChristopherKing's comment [apple docs](https://developer.apple.com/library/ios/documentation/Cocoa/Reference/CoreDataFramework/Classes/NSManagedObjectContext_Class/#//apple_ref/occ/instp/NSManagedObjectContext/undoManager). Be sure to add a `NSUndoManager` to your `NSManagedObjectContext` for it to support `undo` or `rollback` operations. – victor.vasilica Apr 13 '16 at 08:58
2

You might be looking for -refreshObject:mergeChanges: - the docs say that it resets an object from the persistent store, and if you pass NO as the second argument, you can choose not to reapply changes that have been made.

This will likely require you to store a set of objects that you have changed (for the first argument), then clear that set when you commit changes in your context to the store. This should be a pretty trivial addition, though.

Tim
  • 59,527
  • 19
  • 156
  • 165
1

Swift 5

managedObjectContext.rollback()
Community
  • 1
  • 1
shbedev
  • 1,875
  • 17
  • 28