Skip navigation.
 
mlRe: Multiple NSArrayControllers bound to an NSObjectController
FROM : David Spooner
DATE : Fri Nov 09 17:19:04 2007

On 9-Nov-07, at 1:52 AM, Boris Yeltsin wrote:

> I have a model object that has a name and an array attribute. I have 
> an
> array of these model objects bound to an NSArrayController. I can 
> then feed
> another NSArrayController with the array attribute of each model 
> object to
> create  a master-detail inteface. I have one NSTableView that 
> displays the
> model objects' names and then another NSTableView that shows the model
> object's array properties.


To clarify what follows, I will recount my understanding of the 
situation: you have a Model object which has a to-many relationship 
called 'properties', where each element is a Property object with 
attributes corresponding to the columns of your detail table view.


> This works fine. However, as I have been extending this interface
> (incorporating drag 'n drop), I have come up against design issues,
> particularly in the area of undo. I have been creating a lot of code 
> to make
> sure that when I make a change to an NSArrayController's 
> arrangedObjects
> array that any changes which are undone affect the correct model 
> object's
> array. I have to keep track of sortDescriptors, insertion and deletion
> indexes, etc.


I think a better approach is to directly effect the underlying to-many 
relationship 'properties'.  If you have bound the content of your 
detail array controller to the 'properties' of the selected Model then 
any mutation of that relationship will be reflected in the array 
controller.  To do this, have your drop method perform its array 
mutations on

  [selectedModel mutableArrayValueForKey:@"properties"].


Implementing undo support is simplified by adding a category on 
NSMutableArray with methods such as :

  - (void) insertObjects:(NSArray *)objects atIndexes:(NSIndexSet 
*)indices undo:(NSUndoManager *)undo
    {
      [[undo prepareWithInvocationTarget:self] 
removeObjectsAtIndexes:indices undo:undo];
      [self insertObjects:objects atIndexes:indices];
    }


Performing an undo-able move operation can then be written along the 
lines of...

  NSMutableArray *sourceProperties = [sourceModel 
mutableArrayValueForKey:@"properties"];
  NSMutableArray *targetProperties = [targetModel 
mutableArrayValueForKey:@"properties"];
  NSArray *movingProperties = [sourceProperties 
objectsAtIndexes:sourceIndices];
  [sourceProperties removeObjectsAtIndexes:sourceIndices 
undo:myUndoManager];
  [targetProperties insertObjects:movingProperties 
atIndexes:targetIndices undo:myUndoManager];


> As a consequence, I had an idea. What happened if my model object 
> also had
> an NSArrayController in code. When I change selection in the array 
> of my
> model objects, the detail NSTableView is connected to my model 
> object's
> NSArrayController. I feel like this would obviate a lot of 
> management issues
> I am currently experiencing.
>
>
> My array of model objects is bound to an NSArrayController. I 
> thought I
> could use an NSObjectController and bind it to the
> selection.controllerkeyPath of the NSArrayController that controls my
> model objects and use that
> to populate my NSTableView, but it is not working.
>
>
> Does anyone have any insight? I can include a test session.


I would resist the temptation to add controllers to your model 
objects...


> Boris


Cheers,
dave

Related mailsAuthorDate
mlMultiple NSArrayControllers bound to an NSObjectController Boris Yeltsin Nov 9, 09:52
mlRe: Multiple NSArrayControllers bound to an NSObjectController David Spooner Nov 9, 17:19