On Jan 28, 2012, at 13:28 , Mikael Wämundson wrote:

> I have put an NSMutableArray (dataObjectArray) in my class 
> DataObjectCollection. I have also made it possible to add objects to 
> DataObjectCollection and hence the array by implementing
> - (void)addDataObject:(DataObject *)theDataObject
> {
>    NSIndexSet *loneIndex = [NSIndexSet indexSetWithIndex:[[self 
> dataObjectArray] count]];
>    [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:loneIndex 
> forKey:@"dataObjectArray"];
>    [dataObjectArray addObject:theDataObject];
>    [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:loneIndex 
> forKey:@"dataObjectArray"];
> }
> 
> In InterfaceBuilder I have put an ArrayController with ContentArray bound to 
> "myAppDelegate".theDataObjectCollection.dataObjectArray
> I have created bindings between the ArrayController and the columns of an 
> NSTableView is
> 
> Problem:
> Programmatically adding objects to my DataObjectCollection is not observed by 
> the ArrayController.
> 
> I earlier had the dataObjectArray directly in my AppDelegate and then the key 
> value observing worked.
> 
> Is there something I need to do with my class DataObjectCollection to make 
> the observing work, i.e. to make it KVO compliant?

Well, you're doing this the wrong way. Here are the steps, starting over from 
the beginning:

1. Add a NSMutableArray* 'dataObjectArray' instance variable to your 
DataObjectCollection class. This is part of the private implementation, and 
shouldn't be visible to the clients of the class. To make sure of this, 
override '+accessesInstanceVariables' in DataObjectCollection to return NO.

2. Decide on a client-visible (public) property name for your indexed 
collection property. Use a plural noun, such as "dataObjects". Choosing a name 
different from the instance variable name emphasizes the difference between the 
property (public API) and the variable (private backing store).

3. Define a *readonly* "dataObjects" @property for DataObjectCollection, with 
type 'NSArray*' (NOT 'NSMutableArray*'), and implement the getter to return 
'dataObjectArray'.

4. Implement the basic indexed accessor methods:

        -insertObject:inDataObjectsAtIndex:
        -removeObjectFromDataObjectsAtIndex:

5a. If you want a convenience method like 'addDataObject:', implement it like 
this:

        - (void) addDataObject: (DataObject*) dataObject {
                [self insertObject: dataObject inDataObjectsAtIndex: 
self.dataObjects.count];
        }

5b. I happen to prefer not to create such convenience methods (because you 
often end up creating lots of them to parallel the NSArray methods). I usually 
create an auxiliary method:

        @property (readonly) NSMutableArray* mutableDataObject;

implemented like this:

        - (NSMutableArray*) mutableDataObjects {
                return [self mutableArrayValueForKey: @"dataObjects"];
        }

so you can add an object like this:

        [dataObjectCollection.mutableDataObjects addObject];

6. Bind your array controller's content to 
myAppDelegate.theDataObjectCollection.dataObjects.

If you follow these steps, your array property is 100% KVO compliance, *and* it 
cannot be tampered with non-KVO-compliantly from outside, either 
programmatically or via KVC.

(All code typed in Mail, so apologies for any typos and omissions.)


_______________________________________________

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