title: Core Data Undo/Redo - Action depends on what was undone
body: <p>I have  a somewhat complex data model in my iPad application (an OpenGL drawing app), and I'm working on implementing undo/redo functionality. I like the fact that Core Data will undo data model changes for free, but I don't know if the built-in functionality will be sufficient for me.</p>
  
  <p>I have seen lots of examples of undo/redo being implemented in drawing apps, however they generally do the following:</p>
  
  <ol>
  <li>Tell the managed object context to <code>undo</code>.</li>
  <li>Redraw <em>everything</em> on the page from the changed data model.</li>
  </ol>
  
  <p>This is horribly inefficient - in my app I need to be able to perform an action to undo based on the particular object that is being 'undone', and often this means refreshing only part of the canvas.</p>
  
  <p>So my question is this: can I register my own undo operations and use that in conjunction with the built-in undos? For example, say I do the following when the user draws a line:</p>
  
  <pre><code>- (void)drawLineFromPoint:(CGPoint)startPoint toPoint:(CGPoint)endPoint
  {
      // Register the undo operation.
      [[[managedObjectContext undoManager] prepareWithInvocationTarget:self] 
                                                 removeObjectWithIndex:nextObjectIndex];
  
      // Draw the line object.  
      [self drawLineObjectWithIndex:nextObjectIndex fromPoint:startPoint toPoint:endPoint];
  
      // Save the new object to the data model.
      [MyCoreDataHelper saveLineObjectWithIndex:nextObjectIndex fromPoint:startPoint toPoint:endPoint];
  
      nextObjectIndex++;
  }
  </code></pre>
  
  <p>When I come to undo this action, will the invocation be fired <strong>and</strong> the model changed appropriately? Or does this situation require that I abandon the built-in managed object context undo system and roll my own using just the <code>NSUndoManager</code>, including deleting and editing the data model myself? Unless I can tell what the built-in undo/redo is actually undoing, it looks like this could get horribly messy and complicated...</p>
  
  <p><strong>Edit:</strong> I suspect (if the idea above was to work) I would need to wrap it into an undo group, so that my registered undo operation would be grouped with the data model changes?</p>
  
  <p><strong>Another Edit:</strong> Also, can I guarantee the order in which undo actions will be carried out? In other words, if I call <code>undo</code> after the core data changes are saved and my undo action is registered, can I be sure that a deleted entity will be reinstated before my undo action is called?</p>