Undoing Core Data insertions that are performed off the main thread

前端 未结 5 2019
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-30 09:41

I\'m working on some code that uses an NSOperation to import data. I\'d like for the user to be able to undo the NSManagedObject instances that are cre

相关标签:
5条回答
  • 2021-01-30 10:08

    One option may be to make your import thread persistent. Even when the thread is finished importing, it goes into an idle loop state. This way your threaded ManagedObjectContext is persisted in the proper thread. Then when the user wishes to undo a change, send a message to the thread to use the undomanager.

    0 讨论(0)
  • 2021-01-30 10:08

    It's incredibly likely you've considered this and you're likely only looking for a solution using the existing undoManager, but just in case:

    Since you're inserting objects and not updating existing ones, you do have the power to tag them with a transaction id as each batch is imported, deleting them in a background thread in the case of an undo. A simple incremented NSNumber is sufficient for the tag.

    Inelegant, but workable.

    0 讨论(0)
  • 2021-01-30 10:11

    Not an expert, but I think what you're going to need to do is create a second context to perform the operations, then merge the two contexts together. You should be able to manage the merge as an undo step. Note, this only works if you're treating the entire set of operations as one undo step, as far as the user is concerned.

    0 讨论(0)
  • 2021-01-30 10:23

    This answer will probably be a bit of a back and forth. If I understand the issue correctly, you are doing an import but when the import is done you want the user to be able to select what gets saved from the import?

    If that is not correct, please fix my assumptions and I will update this answer.

    If it is correct then what you can do is:

    1. Change your background object creation to

      NSEntityDescription *myEntity = ... //Entity from your context
      [[NSManagedObject alloc] initWithEntity:myEntity
               insertIntoManagedObjectContext:nil];
      
    2. Store these entities in an array.
    3. Pass the entities back to your main thread as needed.
    4. Release on any objects you don't want to keep
    5. Call [myMainContext insertObject:managedObject] on any you want to keep.
    6. Perform a save on the NSManagedObjectContext.

    Since these entities are not part of a NSManagedObjectContext yet they only exist in memory and should be thread safe since they are not yet tied down to a NSManagedObjectContext.

    This is of course theoretical and will require testing. However it should accomplish your goal.

    0 讨论(0)
  • 2021-01-30 10:29

    Suppose that you use a separate context for the background thread, and once it's done, push a [[backgroundContext undoManager] undo] onto the foreground thread's undo stack? I've never tried anything like that, but off the top of my head I can't think of a reason it shouldn't work.

    0 讨论(0)
提交回复
热议问题