Re: an oldie but a goodie: observing properties of collected objects
On Jun 17, 2010, at 10:02 PM, Ken Thomases wrote: Also, you could probably abstract it out into a custom class to facilitate array observing, if you really wanted it. Maybe somebody already has, for all I know. In fact, I put our implementation of this up on github last year: http://github.com/bdrister/DSReceptionist It requires blocks and GC, so not suitable for iOS use as-is, but now that blocks have made their way to iOS, somebody could retrofit old-school memory management into it if they needed and make it dual mode. Best, Benjamin Rister___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
an oldie but a goodie: observing properties of collected objects
This question is a FAQ, but I'm going to ask it anyway. It has been well said by mmalc that Observing a collection is not the same as observing the properties of the objects in a collection. Specifically, in that oh-so-common configuration, an NSMutableArray of MSMutableDictionary objects, if every dictionary has a key @name, I might like to get notified thru KVO if a @name is changed. But there's no simple way to do that. I could register as an observe of @name for every one of those dictionaries, but this is hard to maintain as dictionaries are added to and removed from the array (though, as mmalc shows, it can be done). My question is, does anyone have a *simple* approach to this common problem? (Assume I'm on iPhone OS where NSArrayController is absent.) What advice should one give a newbie on this topic? Just curious - thx - m. -- matt neuburg, phd = m...@tidbits.com, http://www.tidbits.com/matt/ A fool + a tool + an autorelease pool = cool! AppleScript: the Definitive Guide - Second Edition! http://www.tidbits.com/matt/default.html#applescriptthings ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: an oldie but a goodie: observing properties of collected objects
On 2010 Jun 17, at 12:21, Matt Neuburg wrote: My question is, does anyone have a *simple* approach to this common problem? Not necessarily any simpler, but another technique which may be better than observing each object in some situations, (although not yours, without modification). Implement custom setters for properties you want to observe, and in them check for value changes and post notifications. Improve efficiency by coalescing. Watch for infinite loops; posting styles can be helpful. Not a good idea with NSMutableDictionary, though. You'd need to use a custom class instead so you have some real setters. ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: an oldie but a goodie: observing properties of collected objects
On Jun 17, 2010, at 2:21 PM, Matt Neuburg wrote: It has been well said by mmalc that Observing a collection is not the same as observing the properties of the objects in a collection. Specifically, in that oh-so-common configuration, an NSMutableArray of MSMutableDictionary objects, if every dictionary has a key @name, I might like to get notified thru KVO if a @name is changed. But there's no simple way to do that. I could register as an observe of @name for every one of those dictionaries, but this is hard to maintain as dictionaries are added to and removed from the array (though, as mmalc shows, it can be done). It's only hard to maintain if you haven't properly implemented the to-many relationship property with mutating accessors. It is trivial if you have. Proper encapsulation should mean that there is only a tiny number (4 or fewer, I would say) of places in your code which add or remove elements to/from the array. I'm not sure to which example of mmalc's you're referring, but you should implement the mutating indexed accessors for your to-many relationship properties, and always go through those. So, for example (typed in mail): -(void)insertObject:(id) object inWidgetsAtIndex:(NSUInteger)index { [_widgets insertObject:object atIndex:index]; [object addObserver:self forKeyPath:@name options:0 context:myUniqueContext]; } -(void)insertWidgets:(NSArray *)objects atIndexes:(NSIndexSet *)indexes { [_widgets insertObjects:objects atIndexes:indexes]; [_widgets addObserver:self toObjectsAtIndexes:indexes forKeyPath:@name options:0 context:myUniqueContext]; } -(void)removeObjectFromWidgetsAtIndex:(NSUInteger)index { [[_widgets objectAtIndex:index] removeObserver:self forKeyPath:@name]; [_widgets removeObjectAtIndex:index]; } -(void)removeWidgetsAtIndexes:(NSIndexSet *)indexes { [_widgets removeObserver:self fromObjectsAtIndexes:indexes forKeyPath:@name]; [_widgets removeObjectsAtIndexes:indexes]; } Note that only two of the above methods are necessary, one insert and one remove. Implementing the optional replace methods is equally trivial. If you want to observe multiple properties, just implement a class method which returns the set of keys or key paths that you want to observe on all widgets. Then, loop over that set, repeating the addObserver:... and removeObserver:... calls for each. Where's the difficulty, again? Regards, Ken ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: an oldie but a goodie: observing properties of collected objects
On 2010 Jun 17, at 15:33, Ken Thomases wrote: Where's the difficulty, again? I was going to ask what happens if this object which owns 5000 widget objects gets deallocated. Their observers have not been removed and I would expect nastygrams like this [1]. But then I noticed that your observer is 'self'. Ken, is that part of your scheme, that the observer of the collection must also be the owner of the collection? If so, since the objects will be deallocated slightly before the owner is, there is a small window of time where it's observing a deallocated object. Do you worry about that? Or does garbage collection somehow take care of removing observers? (I don't know much about GC.) Jerry [1] 10/06/13 21:32:18 Test[81006] An instance 0x1653cb0 of class Ixterno was deallocated while key value observers were still registered with it. Observation info was leaked, and may even become mistakenly attached to some other object. Set a breakpoint on NSKVODeallocateBreak to stop here in the debugger... ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: an oldie but a goodie: observing properties of collected objects
On Thu, 17 Jun 2010 14:51:04 -0700, Jerry Krinock je...@ieee.org said: On 2010 Jun 17, at 12:21, Matt Neuburg wrote: My question is, does anyone have a *simple* approach to this common problem? Not necessarily any simpler, but another technique which may be better than observing each object in some situations, (although not yours, without modification). Implement custom setters for properties you want to observe, and in them check for value changes and post notifications. Improve efficiency by coalescing. Watch for infinite loops; posting styles can be helpful. Not a good idea with NSMutableDictionary, though Yes, I was afraid that might be the way: Don't use NSMutableDictionary, implement your own model object so you have some more control. It's a pity that key paths break down when they hit an array. @theArray.name accesses all name properties of whatever's in the array, but @theArray[0].name is not a valid path, if you see what I mean... :) On Thu, 17 Jun 2010 17:33:46 -0500, Ken Thomases k...@codeweavers.com said: I'm not sure to which example of mmalc's you're referring, but you should implement the mutating indexed accessors for your to-many relationship properties, and always go through those. So, for example (typed in mail): -(void)insertObject:(id) object inWidgetsAtIndex:(NSUInteger)index { [_widgets insertObject:object atIndex:index]; [object addObserver:self forKeyPath:@name options:0 context:myUniqueContext]; } That's pretending that self, who owns the array, is also the one who wants to do the observing, that it always wants to do it, etc. Obviously that's easy. I'm talking about the general problem of any object registering through the array's vendor to get notified about changes in the array's items' properties. The mmalc solution (in GraphicsBinding) is clear enough - register for changes in the array, and register for changes in the properties of every item in the array individually, and then register on added items or unregister on removed items whenever you hear that the array has altered - but a beginner might find it heavy going. m. -- matt neuburg, phd = m...@tidbits.com, http://www.tidbits.com/matt/ A fool + a tool + an autorelease pool = cool! AppleScript: the Definitive Guide - Second Edition! http://www.tidbits.com/matt/default.html#applescriptthings ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: an oldie but a goodie: observing properties of collected objects
On Jun 17, 2010, at 8:07 PM, Jerry Krinock wrote: I was going to ask what happens if this object which owns 5000 widget objects gets deallocated. Their observers have not been removed and I would expect nastygrams like this [1]. But then I noticed that your observer is 'self'. Ken, is that part of your scheme, that the observer of the collection must also be the owner of the collection? No. If so, since the objects will be deallocated slightly before the owner is, there is a small window of time where it's observing a deallocated object. Do you worry about that? I didn't illustrate it, but you would unregister as an observer from all of the widgets before releasing the widgets array. And, in general, you should make sure that observers unregister before the observed objects are deallocated. That's not unique to the technique I described. Regards, Ken ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: an oldie but a goodie: observing properties of collected objects
On Jun 17, 2010, at 8:16 PM, Matt Neuburg wrote: That's pretending that self, who owns the array, is also the one who wants to do the observing, that it always wants to do it, etc. Obviously that's easy. I'm talking about the general problem of any object registering through the array's vendor to get notified about changes in the array's items' properties. The mmalc solution (in GraphicsBinding) is clear enough - register for changes in the array, and register for changes in the properties of every item in the array individually, and then register on added items or unregister on removed items whenever you hear that the array has altered - but a beginner might find it heavy going. m. True, my example assumed self was the observer. And, yes, that other technique is how you'd do it for other cases. I guess it might be hard for a beginner, but these aren't really beginner-level tasks. Also, you could probably abstract it out into a custom class to facilitate array observing, if you really wanted it. Maybe somebody already has, for all I know. Cheers, Ken ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: an oldie but a goodie: observing properties of collected objects
On Jun 17, 2010, at 7:02 PM, Ken Thomases wrote: you could probably abstract it out into a custom class to facilitate array observing, if you really wanted it. Maybe somebody already has, for all I know. Yeah, that's kind of what I was wondering. Or I guess you could just roll your own version of KVO... m.___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com