Re: Table views with different NSArrayControllers sharing the same data object...
Re: Table views with different NSArrayControllers sharing the same data object...
- Subject: Re: Table views with different NSArrayControllers sharing the same data object...
- From: Quincey Morris <email@hidden>
- Date: Thu, 28 Feb 2008 10:41:07 -0800
On Feb 28, 2008, at 02:46, Keith Blount wrote:
Many thanks for your reply. I have a model object and a view object
- DataList and DataListView. DataList has a -content array. The
DataListView has an array controller whose contentArray is bound to
the DataList's content array. Given that it is the view that
observes the model, I have implemented -
insertObject:inContentAtIndex: and -removeObjectFromContentAtIndex:
in the *view* object, and in these methods it sets itself up as an
observer for newly added list objects.
In the scenario you describe, this seems like the wrong thing to do.
Those two methods are typically used in data models, not in observers
of the data model.
This works fine when there is only one data list view. But if there
are two views that both use the same DataList object's -content
array, this means that each view is *only* set up to observe items
that *it* adds; it will not observe items added by the other view.
So, the second view won't notice when the first view adds another
item to their shared content array and therefore won't update until
you, say, sort the table, and then it won't observe any changes made
to that object, either.
Yes, because you've effectively turned your list views into two
subsidiary data models which are competing for the use of the same
underlying array.
If I move the -insertObject:inContentAtIndex: etc methods to the
model object, though, then I can't add the view as an observer to
the inserted objects as the model knows nothing of the views. Unless
I need to implement these methods in both the view *and* the model,
the view's implementation calling the model's version of these
methods... Given that both the view and the model have a -content
array (the view's -content array is just a retained pointer to the
model's -content array), maybe this is what I need to do?
I think what you need to do is a lot less. The whole purpose of a
NSArrayController is to handle bindings (and therefore observations),
so you need to let it do that or not use one at all. Set the
NSArrayController's object class property to the class of the objects
in the data model array, bind the NSArrayController to the data model,
and bind each DataListView to the (same) NSArrayController's
arrangedObjects. (You usually need to bind just the table columns, and
the table view bindings get set automatically.) If there are buttons
or menu items for adding and deleting objects to the data model, set
their target to the NSArrayController and their action to add: or
remove:. And then with luck you're done.
Beyond that there are increasingly sophisticated levels of
complication, depending on what you're trying to achieve.
If your DataListView needs to use the model data (e.g. to draw a cell
in red if it has a certain value), it can query the data source, which
in this scenario will be the NSArrayController, which in turn will
fetch the value of the appropriate property (based on which table
column you ask for) from the data model.
If your DataListView needs to change the model data (e.g. a custom
table cell editor), it should still use the data source. The
NSArrayController will translate that into setting a property value,
which will automatically trigger KVO notifications that propagate back
to *both* DataListViews for displaying.
If you need some non-default initialization on objects you add to the
data model, then write an action method for whatever object is File's
Owner (NSDocument or NSWindowController, usually) and have that action
method create the object and pass it to the NSArrayController with
addObject:.
If you need the DataListView to itself create a new object for the
data model array, you probably need to rethink your design. :) (If you
*really* need to do it, you can have the view create a new object and
pass it to the NSArrayController with addObject:, I guess.)
If you need to use a custom NSDataSource instead of what
NSArrayController provides for you, then you need to make sure it
changes the data model in a way that triggers KVO notifications
automatically. For properties of objects in the array, it's easy: use
setValue:forKey or set<Key>:. For adding and removing array objects,
it's slightly more obscure ...
What's being giving you trouble, I suspect, is that *the* way to add
an object to an array so that KVO notifications are triggered
automatically is not [arrayOwner.array addObject:] but [[arrayOwner
mutableArrayValueForKey:"array"] addObject:].
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden