Thanks Keary, I will try to focus on one simple hypothetic case, so you (and 
others) can address my question more specifically.

Let's say we have the standard "Organization"->"Department"->"Employee" 
application with two level ordered relations, Each Document representing a 
distinct persistent store with a single Organization and its departments and 
employes. The window shows (source/detail) Departments by ordered relation and 
Employees table by ordered relation to department.

In my document NSWindowController, there are two references, to the 

@property (atomic, readwrite, weak) NSManagedObject *currentDepartment; // and 
@property (atomic, readwrite, weak) NSManagedObject *currentEmployee;

(I know this example calls for using the table or array controller selection 
instead of those references, but my case has no "selection" per se. I need 
those "current" references, to which I apply actions and changes as the program 
runs.)

Consider the following menu item IBActions:  "Next Department" and "Next 
Employee". 

"Next Department" will look if the currentDepartment is the last on the 
relation. if not, it will set the currentDepartment reference to the next one 
(may change from nil to first Department). Otherwise (currentDepartment is 
last) it will create a new Department entity, and set the reference to it. 
Last, it will invoke the "Next Employee" (below) action.

"Next Employee" is similar. it looks if the currentEmployee is the last on the 
relation. if not, it will change the currentEmployee reference to the next one 
(may change from nil to first Employee). Otherwise (currentEmployee is last) it 
will create a new Employee entity, and set the reference to it.

After several iterative "Next Department" and "Next Employee" actions from the 
user, we have several entities, and two references to some department and 
employee --- not necessarily the last ones. I'd like "Undo" from the user, to 
do EXACTLY what it does today, reverting the creation of new departments and 
employees, but also to revert the changes of those references.

From what I've read so far, I guess I need to register my own "Undo" actions in 
the "Next Department" and "Next Employee" implementations. But ---

* Onto what NSUndoManager?
* When should I do this? before, or after my calls to CoreData?
* How can I be sure that my own undo actions are correctly grouped with those 
CoreData registers?
* Will this work in cases where "Next Employee" or "Next Department" move 
within existing entities, and do not create any entities? 

I'm sorry to drag you all into this level of programming --- but the question 
is actually how to synchronize with CoreData undo management, if your 
application is not just plain CoreData, and has more logic to it --- which I 
think is the common case. 

Apple's documentation doesn't explain how to synchronize different 
NSUndoManagers, or assumes they are "Nested" in the sense that an Undo action 
only reaches ONE NSUndoManager. 

Again --- any thought or hint, or reference to as code sample (best from Apple) 
will be greatly appreciated.

On 24 באוג 2014, at 23:38, Keary Suska <cocoa-...@esoteritech.com> wrote:

> On Aug 24, 2014, at 9:07 AM, Motti Shneor <su...@bezeqint.net> wrote:
> 
>> My OS-X app is using ARC, is CoreData Document-Based (using the old 
>> NSPersistentDocument) and uses 10.9 SDK. 
>> 
>> Up until now, I did nothing on my behalf to support user Undo/Redo, still 
>> the application seemed to work fine. I was very impressed with Cocoa (this 
>> millionth time).
>> 
>> However. In some of my application controller  objects, I maintain and rely 
>> on references to CoreData entities (NSManagedObject instances) for the 
>> application state (The current entity I'm working on, etc.) 
>> 
>> When user selects "Undo" (or cmd-Z) - my controllers lose track of the 
>> application state. Last created entities get deleted by Core-Data, and my 
>> references point to dead entities. In short - I lose synchronization with my 
>> model.
>> 
>> If I set those entity references to "strong" then the NSManagedObjects can't 
>> be released of course, but I'll soon crash because they were deleted from 
>> CoreData. If I make them weak references insted, they will nullify upon undo 
>> --- but no one will ever set these references to their previous values (the 
>> older state). 
>> 
>> It seems I need to add my own "undo actions" to the automatic mechanism, but 
>> I don't know WHEN is the right time to do it, WHAT undo-managed I should 
>> address, and HOW to group my "undo" and "redo" actions, with the CoreData's 
>> undo actions.
>> 
>> I tried to dive into the Undo architecture documentation, but got confused 
>> very soon, especially because CoreData does its thing independently of other 
>> parts of my program.
>> 
>> Any hint or sample-code reference, or clarifying note will be greatly 
>> appreciated!
> 
> There is not likely a single solution to what you are after. AFAIK, there is 
> no reliable way to track what the managed object context is doing vis a vis 
> undo. You can, however, decide whether undo can happen, to what undo manager 
> object undos will be registered and whether they are registered at all. You 
> can also watch for the NSManagedObjectContextObjectsDidChangeNotification 
> notification, and query the objects to see if it effects your controller's 
> states. You can also use multiple managed object contexts with different undo 
> managers, and reconcile them later. What you specifically need to do will 
> determine the best approach.
> 
> Keary Suska
> Esoteritech, Inc.
> "Demystifying technology for your home or business"
> 

Motti Shneor
e-mail: motti.shn...@gmail.com
phone: +972-8-9267730
mobile: +972-54-3136621
----------------------------------------
Ceterum censeo Microsoftinem delendam esse



_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to