Re: Key Value Observing of NSMutableArray inside an object
Re: Key Value Observing of NSMutableArray inside an object
- Subject: Re: Key Value Observing of NSMutableArray inside an object
- From: Quincey Morris <email@hidden>
- Date: Sat, 28 Jan 2012 15:07:44 -0800
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 (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