Re: -[NSDocument fileURL] is observable (KVO). Documented?
Kyle gave the long answer. But, if it isn’t documented, don’t count on it (although there is some backfill required there). Also, being KVO compliant doesn’t necessarily mean you can simply bind to it, as you can’t be sure that the result will be returned on the main thread. KVO compliance documentation is in place where it is known (typically in new classes) and will be updated in older classes as possible/info is available. On Jun 1, 2010, at 5:15 PM, Mike Abdullah wrote: By default Cocoa classes use automatic KVO. So long as Cocoa always changes the URL by calling -setFileURL: you will get proper notifications. On 1 Jun 2010, at 22:02, Jerry Krinock wrote: There is no mention in -[NSDocument fileURL] documentation, nor in 10.5 or 10.6 release notes, that this property is observable using KVO. But when I added some code to do this, created a document, and renamed the document in Finder while the document was open, my observer logged a hit. Is there some underlying or other documentation I don't know about? Jerry Krinock - (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context { NSLog(@2796: keyPath %@ observed:\n%@, keyPath, change) ; } - (id)init { self = [super init] ; if (self != nil) { [self addObserver:self forKeyPath:@fileURL options:NSKeyValueObservingOptionNew context:NULL] ; } return self ; } - (void)dealloc { [self removeObserver:self forKeyPath:@fileURL] ; ...; [super dealloc]; } ___ 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/cocoadev%40mikeabdullah.net This email sent to cocoa...@mikeabdullah.net ___ 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/scott%40cocoadoc.com This email sent to sc...@cocoadoc.com ___ 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-establishing KVO in Managed objects after undo
Hi, I have some places in my code where I have managed objects that need to observe various key paths. If one of these objects has been deleted by the user, and then they undo, I need to re-establish the KVO. As undo doesn't call awakeFromFetch, I need to do this somewhere else. I have awakeFromSnapshotEvents: implemented for 10.6+ users, and it works fine, but is only available in 10.6, whereas I need to also have something that will work on 10.5. How did you accomplish this before 10.6? TIA Gideon ___ 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: Re-establishing KVO in Managed objects after undo
There's no easy way to do this. But if you are observing other managed objects, you might be able to use +(NSSet*)keyPathsForValuesAffectingKey instead. (Search for registering dependent keys in the docs.) If you are observing something that is not part of your data model, you might try using mechanisms other than KVO to keep your data model updated. KVO can be a world of hurt when used the way you are using it. There are old threads on this topic. See, for example, Strange NSManagedObjectContextObjectsDidChangeNotification behavior. Dave On 2010-05-01, at 9:42 AM, Gideon King wrote: Hi, I have some places in my code where I have managed objects that need to observe various key paths. If one of these objects has been deleted by the user, and then they undo, I need to re-establish the KVO. As undo doesn't call awakeFromFetch, I need to do this somewhere else. I have awakeFromSnapshotEvents: implemented for 10.6+ users, and it works fine, but is only available in 10.6, whereas I need to also have something that will work on 10.5. How did you accomplish this before 10.6? TIA Gideon ___ 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/dave.fernandes%40utoronto.ca This email sent to dave.fernan...@utoronto.ca ___ 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: Re-establishing KVO in Managed objects after undo
On Sat, May 1, 2010 at 9:34 AM, Dave Fernandes dave.fernan...@utoronto.ca wrote: If you are observing something that is not part of your data model, you might try using mechanisms other than KVO to keep your data model updated. KVO can be a world of hurt when used the way you are using it. There are old threads on this topic. See, for example, Strange NSManagedObjectContextObjectsDidChangeNotification behavior. Agreed. Your controller should listen for MOC notifications to find out when to start and stop observing objects. After all, that's what NSArrayController does. --Kyle Sluder ___ 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: Re-establishing KVO in Managed objects after undo
Thanks guys - will look into that. On 02/05/2010, at 3:11 AM, Kyle Sluder wrote: On Sat, May 1, 2010 at 9:34 AM, Dave Fernandes dave.fernan...@utoronto.ca wrote: If you are observing something that is not part of your data model, you might try using mechanisms other than KVO to keep your data model updated. KVO can be a world of hurt when used the way you are using it. There are old threads on this topic. See, for example, Strange NSManagedObjectContextObjectsDidChangeNotification behavior. Agreed. Your controller should listen for MOC notifications to find out when to start and stop observing objects. After all, that's what NSArrayController does. --Kyle Sluder ___ 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: Re-establishing KVO in Managed objects after undo
Gideon King (gid...@novamind.com) on 2010-05-01 09:42 said: Hi, I have some places in my code where I have managed objects that need to observe various key paths. Why? (I'm curious... I've never used such a pattern.) Perhaps instead you could override setters so that they perform other actions in addition to just changing the attribute/relationship. Sean ___ 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: Re-establishing KVO in Managed objects after undo
It's inherited code from someone else, and am trying to work that out myself too...luckily there are only 5-6 of them, so I should be able to sort it out. Just looking at it now, I think a little refactoring should sort it out, and remove the need for KVO. On 02/05/2010, at 5:23 AM, Sean McBride wrote: Gideon King (gid...@novamind.com) on 2010-05-01 09:42 said: Hi, I have some places in my code where I have managed objects that need to observe various key paths. Why? (I'm curious... I've never used such a pattern.) Perhaps instead you could override setters so that they perform other actions in addition to just changing the attribute/relationship. Sean ___ 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
Crash on NSKVOPendingNotificationRelease (KVO, bindings issue?)
I'm using KVO as a generalized recalculation engine, somewhat akin to how a spreadsheet recalcuates values based on what's changed. It's mostly successful once you eliminate cycles, but there is a persistent problem. On each relevant object, I have a observeValueForKeyPath:ofObject:change:context: method which then triggers willChangeValueForKey: / didChangeValueForKey: for dependent properties. I've noticed that when observeValueForKeyPath:ofObject:change:context gets called more than once in a row for an object, one of the other observed objects dies in didChangeValueForKey: -- here's the stack trace Program received signal: “EXC_BAD_ACCESS”. #0 0x7fff84d31ae1 in NSKVOPendingNotificationRelease #1 0x7fff88aa0bd3 in __CFArrayReleaseValues #2 0x7fff88a815f8 in _CFArrayReplaceValues #3 0x7fff84d31e35 in NSKeyValuePopPendingNotificationPerThread #4 0x7fff84d31dca in NSKeyValueDidChange #5 0x7fff84d1574f in -[NSObject(NSKeyValueObserverNotification) didChangeValueForKey:] #6 0x1000181c8 in -[CMEdge didChangeValueOnceForKey:] at CMEdge.m:133 #7 0x100019f51 in -[CMNode observeValueForKeyPath:ofObject:change:context:] at CMNode.m:222 The only workaround is to perform the didChangeValueForKey: in the next event cycle i.e. by using performSelectorOnMainThread:withObject:waitUntilDone: Not really ideal especially since I'm worried I'm just covering up the root of the problem, whatever it is. Any ideas on the cause? Side question: I can of course use keyPathsForValuesAffectingValueForKey: and friends to declare the dependencies instead of using a procedure to react to them, but I need to execute code as well e.g. update the observed value. For example, say A = B/C. When either B or C changes, you want A to change too. I can use keyPathsForValuesAffectingA to declare it depends on B or C, but I need to update the cached A value whenever B or C changes -- how would I do that without using observeValueForKeyPath:ofObject:change:context:? Cheers Glen Low Pixelglow Software___ 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: Crash on NSKVOPendingNotificationRelease (KVO, bindings issue?)
On Apr 21, 2010, at 17:47, Glen Low wrote: I'm using KVO as a generalized recalculation engine, somewhat akin to how a spreadsheet recalcuates values based on what's changed. It's mostly successful once you eliminate cycles, but there is a persistent problem. The likely answer (see below for the reasons) is that this is probably not a good approach. Your application needs a specific behavior of change propagation, cycle elimination -- as well as other possible constraints -- that KVO has no API contract to provide. I'd recommend you spend the effort on designing your own object graph and related behavior. On each relevant object, I have a observeValueForKeyPath:ofObject:change:context: method which then triggers willChangeValueForKey: / didChangeValueForKey: for dependent properties. I've noticed that when observeValueForKeyPath:ofObject:change:context gets called more than once in a row for an object, one of the other observed objects dies in didChangeValueForKey: -- here's the stack trace I *believe* that KVO contains at least one (major? inherent?) bug that causes crashes like this with certain patterns of observations. Whenever I run into such crashes, I've never been able to work out whether it is in fact a bug, or if I did something wrong, nor to recreate the crash in a more controlled context that could be used as the basis of a bug report. So you might have run into a bug. Or you might have set up an observation pattern that KVO doesn't really support (either at the level of observers or the level of notifications). KVO has two important defects from the developer's point of view: it's a black box system, so trying to understand what it's doing at any given moment is pure guesswork; and it's an implementation-defined system, so that beyond its general responsibilities, what is does is what it's supposed to do, and there's no independent standard of whether it's right or wrong. Plus, KVO probably doesn't scale well as the number of observations increases. If your object graph is going to get large, performance may well become a consideration. For all those reasons, I wouldn't suggest using it for an application like this, where *propagation* of the notifications across multiple objects is the key functional issue. FWIW. Side question: I can of course use keyPathsForValuesAffectingValueForKey: and friends to declare the dependencies instead of using a procedure to react to them, but I need to execute code as well e.g. update the observed value. For example, say A = B/C. When either B or C changes, you want A to change too. I can use keyPathsForValuesAffectingA to declare it depends on B or C, but I need to update the cached A value whenever B or C changes -- how would I do that without using observeValueForKeyPath:ofObject:change:context:? If you really need to cache the A value, then you have to use observeValueForKeyPath:ofObject:change:context:. Using keyPathsForValuesAffectingA only makes sense if you're going to produce the A value on demand. Incidentally, this example points another defect of using KVO for your application. You want A to change when B or C changes, and it will -- literally, meaning twice. Once for the B change, and once for the C change. That means that A may temporarily have an invalid value, and that might itself be propagated via notifications before its final value is calculated. KVO guarantees no order for the notifications, and although in a few cases it might optimize some repeated notifications away you don't have a lot of control over the quantity of notifications that get sent. ___ 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
CGPoint and KVO
I have a property which is a CGPoint and I'm observing it. I didn't really know what to expect in the change dictionary (I have NSKeyValueObservingOld as the observation flags) so I stuck in a breakpoint and went looking. After messing about in the debugger when the property was changed I found the old value was an NSConcreteValue and the following code appears to work to extract the CGPoint from it CGPoint oldPoint; id oldValue = [ change valueForKey:NSKeyValueChangeOld ]; [ (NSValue*)oldValue getValue:oldPoint ] Is this correct? I've failed to find anything much in the KVO documentation about CGPoint or how I should expect to receive structs or other primitives. This is iPhone OS (incase that makes a difference). ___ 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: CGPoint and KVO
On 04/04/2010, at 1:40 AM, Roland King wrote: I have a property which is a CGPoint and I'm observing it. I didn't really know what to expect in the change dictionary (I have NSKeyValueObservingOld as the observation flags) so I stuck in a breakpoint and went looking. After messing about in the debugger when the property was changed I found the old value was an NSConcreteValue and the following code appears to work to extract the CGPoint from it CGPoint oldPoint; id oldValue = [ change valueForKey:NSKeyValueChangeOld ]; [ (NSValue*)oldValue getValue:oldPoint ] Is this correct? I've failed to find anything much in the KVO documentation about CGPoint or how I should expect to receive structs or other primitives. In the case of NSPoint/CGPoint: CGPoint oldPoint = [oldValue pointValue]; This is iPhone OS (incase that makes a difference). ___ 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/kiel.gillard%40gmail.com This email sent to kiel.gill...@gmail.com ___ 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: CGPoint and KVO
Thanks pointValue didn't work on iPhone OS but CGPointValue did, luckily, as that's the one I needed. That seems to be a UIKit extension. I've switched to that. was my original method (apart from being clunky) wrong? It did work. On 03-Apr-2010, at 10:43 PM, Kiel Gillard wrote: On 04/04/2010, at 1:40 AM, Roland King wrote: I have a property which is a CGPoint and I'm observing it. I didn't really know what to expect in the change dictionary (I have NSKeyValueObservingOld as the observation flags) so I stuck in a breakpoint and went looking. After messing about in the debugger when the property was changed I found the old value was an NSConcreteValue and the following code appears to work to extract the CGPoint from it CGPoint oldPoint; id oldValue = [ change valueForKey:NSKeyValueChangeOld ]; [ (NSValue*)oldValue getValue:oldPoint ] Is this correct? I've failed to find anything much in the KVO documentation about CGPoint or how I should expect to receive structs or other primitives. In the case of NSPoint/CGPoint: CGPoint oldPoint = [oldValue pointValue]; This is iPhone OS (incase that makes a difference). ___ 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/kiel.gillard%40gmail.com This email sent to kiel.gill...@gmail.com ___ 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: CGPoint and KVO
The main issue with the original code is that it assumes that the value is a CGPoint. If it were anything smaller, you'd get garbage values in your point, and if it were any larger, you'd be stomping on memory as you ran off the end of your CGPoint variable. Any time you use -[NSValue getValue:], you should check to make sure that the NSValue represents the correct type. Sent from my iPad On Apr 3, 2010, at 7:52, Roland King r...@rols.org wrote: Thanks pointValue didn't work on iPhone OS but CGPointValue did, luckily, as that's the one I needed. That seems to be a UIKit extension. I've switched to that. was my original method (apart from being clunky) wrong? It did work. On 03-Apr-2010, at 10:43 PM, Kiel Gillard wrote: On 04/04/2010, at 1:40 AM, Roland King wrote: I have a property which is a CGPoint and I'm observing it. I didn't really know what to expect in the change dictionary (I have NSKeyValueObservingOld as the observation flags) so I stuck in a breakpoint and went looking. After messing about in the debugger when the property was changed I found the old value was an NSConcreteValue and the following code appears to work to extract the CGPoint from it CGPoint oldPoint; id oldValue = [ change valueForKey:NSKeyValueChangeOld ]; [ (NSValue*)oldValue getValue:oldPoint ] Is this correct? I've failed to find anything much in the KVO documentation about CGPoint or how I should expect to receive structs or other primitives. In the case of NSPoint/CGPoint: CGPoint oldPoint = [oldValue pointValue]; This is iPhone OS (incase that makes a difference). ___ 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/kiel.gillard%40gmail.com This email sent to kiel.gill...@gmail.com ___ 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/clarkcox3%40gmail.com This email sent to clarkc...@gmail.com ___ 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
KVO on NSDictionary elements
Hello all. Im implementing a live filter, and each, time I insert a filter in the filterDictionary the controller (which is another class) gets notified about the insertion.\ I was reading the KVO, and its says something about NSKeyValueChangeKindKey. So this is what Im doing in the Controller class: [_filterController addObserver:self forKeyPath:@_filterSettings options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld) context:NULL]; so I undertand that as it is above I will get notified only when I setUp a new NSDictionary in the ivar _filterSettings, obviously Im not getting notified when I insert something in the _filterSettings dictionary. How should I add the observer? is it possible to do so? thanks Gustavo ___ 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: KVO and object release timing (for a NSCollectionView)
Hi Corbin, I have a NSButton in C to remove from the array controller the A object it represents. However, each time I click on that button, I first get a warning telling me that I remove an observed object before releasing the observer, and then the program crash, If you have a crash, it is always best to post the crash report. Well, I wrote a workaround, so I can't give you a crash report anymore. The crash happens in the KVO unregistering routine. The problem is that when the represented object is removed from the array controller, the corresponding NSView is not immediately released. Instead, there is an implied CAAnimation (or something similar) that makes the NSView slowly fade away. Net result is that the NSView survives some tenths of a second after the represented object is released, and the KVO unregistering crashes. The (very dirty) workaround is this: instead of immediately release the represented object, retain it, target it for delayed deletion, and then remove it from the array; the real deletion is triggered in the dealloc routine of the corresponding NSView (or subclass thereof) : // Highly heterodox - (void)dealloc { [super dealloc]; NSApp delegate] appController] layerManager] removeTargetedCALayer]; } I had to write it this way, instead of the more orthodox : - (void)dealloc { NSApp delegate] appController] layerManager] removeTargetedCALayer]; [super dealloc]; } because the KVO removal takes place in the [super dealloc] routine… Great WE, Vincent___ 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: KVO and object release timing (for a NSCollectionView)
On Sat, Jan 23, 2010 at 1:48 AM, vincent habchi vi...@macports.org wrote: The problem is that when the represented object is removed from the array controller, the corresponding NSView is not immediately released. Instead, there is an implied CAAnimation (or something similar) that makes the NSView slowly fade away. Net result is that the NSView survives some tenths of a second after the represented object is released, and the KVO unregistering crashes. Hooray for retain cycles; if you avoid them you get overrelease bugs! (I can't wait for garbage collection.) This happens a lot in any non-trivial context. You might want to have some sort of notification or delegate method that keeps your object alive long enough. Putting code after calling [super dealloc] is usually a bad idea, because self will be a garbage pointer, and how many of us are so careful about pointer lifetimes that we're immune to writing use-after-free bugs, especially when we return to the code six months later? --Kyle Sluder ___ 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
KVO and object release timing (for a NSCollectionView)
Hi again, in my project, I have a managed object A, that has a relationship to an other managed object B, itself in relation with a third object C (which happens to be a CALayer, therefore is not part of Core Data): A - B - C. The object A I register in a NSArrayController, whose content is linked to a NSCollectionView. The NSView I use to visually represent the NSArrayController contents includes a slider that observes a parameter of C (more specifically, opacity) through KVO. So far, so good. I have a NSButton in C to remove from the array controller the A object it represents. However, each time I click on that button, I first get a warning telling me that I remove an observed object before releasing the observer, and then the program crash, albeit: - I've set the relation option between A and B to leave B alone when A is deallocated; - I keep a temporary pointer on A and release C before A is removed from the array controller. NSArrayController controller; id A, B, C (void)removeA:(id)sender { id tmp = [A retain]; [controller removeObject:A]; [[[A getB] getC] release]; [[A getB] release]; [tmp release]; } It seems the object in the NSCollectionView persists some time after A is removed from the array. Of course, I could twist the action and redirect it somehow to the slider so it would unregister (which would mean somehow subclassing it) and then pass a message the remove message to A. Is there any simpler solution ? I hope this is not too obscure. Thanks, Vincent___ 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: KVO and object release timing (for a NSCollectionView)
On Jan 22, 2010, at 7:01 AM, vincent habchi wrote: I have a NSButton in C to remove from the array controller the A object it represents. However, each time I click on that button, I first get a warning telling me that I remove an observed object before releasing the observer, and then the program crash, If you have a crash, it is always best to post the crash report. --corbin ___ 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: How to know whether property in Cocoa class is KVO-compliant?
On Jan 10, 2010, at 11:18 PM, Dave Fernandes wrote: Look for Cocoa Bindings Guide in the docs. It would be nice if it were cross-referenced in every class description. Please file a bug about that. Class methods that are KVO compatible are stated as such in the reference. They aren’t pervasive at this point, but many more became KVO compatible in Snow Leopard. I think it’s safe to expect more methods will become KVO compliant in the future. And the reference will be updated to reflect those that are. ___ 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: How to know whether property in Cocoa class is KVO-compliant?
On Jan 10, 2010, at 19:58, Jerry Krinock wrote: After studying some about bindings during the last week, I decided that, just for fun, I would bind an NSSegmentedControl to its window controller using a binding instead of target/action. I thought that selectedSegment might be a KVO-compliant property of NSSegmentedControl because it has a -selectedSegment and -setSelectedSegment: method. So I exposed a binding named @foo in my window controller's +initialize, in -awakeFromNib I added this: [windowController bind:@foo toObject:segmentedControl withKeyPath:@selectedSegment options:0] ; Adding on to mmalc's response, to make this explicit: You *didn't* bind an NSSegmentedControl to its window controller, you actually bound a window controller['s foo binding] to [the selectedSegment property of] a NSSegmentedControl. IIRC the bindings documentation isn't clear which direction is bound to refers to and/or it gives the impression that a binding is symmetric (which it may effectively be at the level of notifications, but it isn't at the level of establishing bindings between objects). ___ 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: Bindings; Was: whether property in Cocoa class is KVO-compliant?
On 2010 Jan 11, at 03:47, Quincey Morris wrote: On Jan 10, 2010, at 19:58, Jerry Krinock wrote: toObject:segmentedControl You *didn't* bind an NSSegmentedControl to its window controller, you actually bound a window controller['s foo binding] to [the selectedSegment property of] a NSSegmentedControl. Oops, you're correct. Like the method says, bind:*to*:segmentedControl. IIRC the bindings documentation isn't clear which direction is bound to refers to and/or it gives the impression that a binding is symmetric (which it may effectively be at the level of notifications, but it isn't at the level of establishing bindings between objects). When I first heard the word binding, from other uses in English, I assumed that it was two-way, and labored under this incorrect assumption for quite awhile. Now I know that a binding is only one way, and further that change data flows in the *opposite* direction of the *to*. That is, if I bind myself *to* you, I observe what you do and your changes flow back *to* me. I wonder why bindings was not as an extension of KVO, instead of as a separate sideshow. The effect is the same as KVO, with the addition that a designated setter is automatically invoked in the observer when a change is observed. And then there's the whole thing about the separate namespaces for bindings and properties, not to mention the three definitions of the word binding to mean 1. (verb) the act of binding 2. (noun) the connection that you get when you make a binding 3. (noun) the name of the property that gets bound in the receiver I wrote a little document for myself where I actually use the words binding(1), binding(2) and binding(3). Scott, if I ever get to point that I think I know what I'm talking about, I might file a bug to suggest that the whole Cocoa Bindings Reference be destroyed and its pages page added as a Bindings section to the regular API documentation of the bound classes. Thanks for the discussion. I hope I didn't make any more bind mistakes in the above! ___ 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: Bindings; Was: whether property in Cocoa class is KVO-compliant?
On 11 Jan 2010, at 17:01, Jerry Krinock wrote: On 2010 Jan 11, at 03:47, Quincey Morris wrote: On Jan 10, 2010, at 19:58, Jerry Krinock wrote: toObject:segmentedControl You *didn't* bind an NSSegmentedControl to its window controller, you actually bound a window controller['s foo binding] to [the selectedSegment property of] a NSSegmentedControl. Oops, you're correct. Like the method says, bind:*to*:segmentedControl. IIRC the bindings documentation isn't clear which direction is bound to refers to and/or it gives the impression that a binding is symmetric (which it may effectively be at the level of notifications, but it isn't at the level of establishing bindings between objects). When I first heard the word binding, from other uses in English, I assumed that it was two-way, and labored under this incorrect assumption for quite awhile. Now I know that a binding is only one way, and further that change data flows in the *opposite* direction of the *to*. That is, if I bind myself *to* you, I observe what you do and your changes flow back *to* me. I wonder why bindings was not as an extension of KVO, instead of as a separate sideshow. The effect is the same as KVO, with the addition that a designated setter is automatically invoked in the observer when a change is observed. What makes you say this? Bindings do work by using KVO. The default implementation calls -setValue:forKey: when it detects a change, but any object is free to handle a binding any way it likes. (Most of AppKit as far as I can tell uses a customised process that doesn't retain the target object).___ 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: Bindings; Was: whether property in Cocoa class is KVO-compliant?
On 2010 Jan 11, at 09:46, Mike Abdullah wrote: I wonder why bindings was not as an extension of KVO, instead of as a separate sideshow. The effect is the same as KVO, with the addition that a designated setter is automatically invoked in the observer when a change is observed. What makes you say this? Because when bindings observes a change, it uses KVO *and* invokes a special observer method, as you note ... Bindings do work by using KVO. The default implementation calls -setValue:forKey: when it detects a change, but any object is free to handle a binding any way it likes. Well, I guess I'm talking about the default implementation then. I just mean I'd probably have an easier time learning bindings if they were called maybe KVO Plus, and somehow used a class' regular properties on both ends of a binding, instead of defining this separate bindings namespace with definitions that often duplicate the regular properties. ___ 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: Bindings; Was: whether property in Cocoa class is KVO-compliant?
On Jan 11, 2010, at 9:01 am, Jerry Krinock wrote: I wonder why bindings was not as an extension of KVO, instead of as a separate sideshow. The effect is the same as KVO, It's not at all. Bindings uses KVO to ensure that things are kept synchronised; KVO is a general mechanism that allows one object to receive a notification when the value of a property changes. What it does in response is entirely up to it. mmalc ___ 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: Bindings; Was: whether property in Cocoa class is KVO-compliant?
On Jan 11, 2010, at 10:04, Jerry Krinock wrote: Well, I guess I'm talking about the default implementation then. I just mean I'd probably have an easier time learning bindings if they were called maybe KVO Plus, and somehow used a class' regular properties on both ends of a binding, instead of defining this separate bindings namespace with definitions that often duplicate the regular properties. My *guess* is that bindings were originally intended to use properties on both ends (note that the -[NSObject bind: ...] documentation *still* says this), but developed from there so that one end was something more general with its own namespace. To me, the Cocoa Bindings Reference document reads as if it were written under this incorrect assumption, and then not-quite-thoroughly corrected later. That's one piece of documentational obscurity. Binding *are* bi-directional, in the general sense that they're supposed to allow a property value to be modified from either end of the binding. However, the individual frameworks technology pieces from which bindings are constructed are all uni-directional. That's another piece of documentational obscurity. I only recently figured out that Cocoa binding != binding: although all Cocoa bindings are bindings, not all bindings are Cocoa bindings. That's a third piece of documentational obscurity -- although the fact that it took me 2 years to figure it out possibly reflects badly on me rather than the documentation. I now believe that Cocoa bindings are distinguished by (amongst other things) special (meaning, going beyond KVC) handling for key paths involving NSController objects, although this is undocumented apart from the occasional hint. More documentational obscurity. ___ 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
How to know whether property in Cocoa class is KVO-compliant?
After studying some about bindings during the last week, I decided that, just for fun, I would bind an NSSegmentedControl to its window controller using a binding instead of target/action. I thought that selectedSegment might be a KVO-compliant property of NSSegmentedControl because it has a -selectedSegment and -setSelectedSegment: method. So I exposed a binding named @foo in my window controller's +initialize, in -awakeFromNib I added this: [windowController bind:@foo toObject:segmentedControl withKeyPath:@selectedSegment options:0] ; and finally in a windowWillClose cleanup method I added an unbind:. The above code compiled and ran without any bitchin' from out of the console, and at any time in the program if I send -infoForBinding:@foo to windowController, I log the expected result: bindingInfo = { NSObservedKeyPath = selectedSegment; NSObservedObject = NSSegmentedControl: 0x1b879c90; NSOptions = { NSMultipleValuesPlaceholder = null; NSNoSelectionPlaceholder = null; NSNotApplicablePlaceholder = null; NSNullPlaceholder = null; NSRaisesForNotApplicableKeys = 1; NSValueTransformer = null; NSValueTransformerName = null; }; } But it just didn't work. Flipping that segmented control in the user interface never caused my window controller's -setFoo: to run. Did I do anything wrong? If not, I conclude that NSSegmentedControl's is not KVO-compliant for property 'selectedSegment'. That is, the class implementation probably changes the view without invoking the setter. I changed to target/action and it works fine. So how does one know whether a property in Cocoa class is KVO-compliant? I can't find an answer in the Key-Value Observing Programming Guide. I thought maybe there's a little point system: 1. Property has a setter and getter; i.e. -bar and -setBar:. Add 2 points. 2. I remember seeing, every now and then, in newer API documentation, a notation that this property is observeable, or something like that. Add 8 points. 3. Add 1 point for each Mac OS X dot release that the class first appeared in. 0 points for 10.0, 1 point for 10.1, etc. 4. If the class is a view layer class, subtract 2 points. Most people don't usually bind to view classes. 5. Test it and see if it works. Add 5 points. What is the possibility that it could stop working in a future Mac OS X release? ___ 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: How to know whether property in Cocoa class is KVO-compliant?
Look for Cocoa Bindings Guide in the docs. It would be nice if it were cross-referenced in every class description. SelectedIndex should work for a segmented control. Haven't tried it myself though. Cheers, Dave On 2010-01-10, at 10:58 PM, Jerry Krinock wrote: After studying some about bindings during the last week, I decided that, just for fun, I would bind an NSSegmentedControl to its window controller using a binding instead of target/action. I thought that selectedSegment might be a KVO-compliant property of NSSegmentedControl because it has a -selectedSegment and -setSelectedSegment: method. So I exposed a binding named @foo in my window controller's +initialize, in -awakeFromNib I added this: [windowController bind:@foo toObject:segmentedControl withKeyPath:@selectedSegment options:0] ; and finally in a windowWillClose cleanup method I added an unbind:. The above code compiled and ran without any bitchin' from out of the console, and at any time in the program if I send -infoForBinding:@foo to windowController, I log the expected result: bindingInfo = { NSObservedKeyPath = selectedSegment; NSObservedObject = NSSegmentedControl: 0x1b879c90; NSOptions = { NSMultipleValuesPlaceholder = null; NSNoSelectionPlaceholder = null; NSNotApplicablePlaceholder = null; NSNullPlaceholder = null; NSRaisesForNotApplicableKeys = 1; NSValueTransformer = null; NSValueTransformerName = null; }; } But it just didn't work. Flipping that segmented control in the user interface never caused my window controller's -setFoo: to run. Did I do anything wrong? If not, I conclude that NSSegmentedControl's is not KVO-compliant for property 'selectedSegment'. That is, the class implementation probably changes the view without invoking the setter. I changed to target/action and it works fine. So how does one know whether a property in Cocoa class is KVO-compliant? I can't find an answer in the Key-Value Observing Programming Guide. I thought maybe there's a little point system: 1. Property has a setter and getter; i.e. -bar and -setBar:. Add 2 points. 2. I remember seeing, every now and then, in newer API documentation, a notation that this property is observeable, or something like that. Add 8 points. 3. Add 1 point for each Mac OS X dot release that the class first appeared in. 0 points for 10.0, 1 point for 10.1, etc. 4. If the class is a view layer class, subtract 2 points. Most people don't usually bind to view classes. 5. Test it and see if it works. Add 5 points. What is the possibility that it could stop working in a future Mac OS X release? ___ 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/dave.fernandes%40utoronto.ca This email sent to dave.fernan...@utoronto.ca ___ 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: How to know whether property in Cocoa class is KVO-compliant?
On Jan 10, 2010, at 8:18 pm, Dave Fernandes wrote: Look for Cocoa Bindings Guide in the docs. It would be nice if it were cross-referenced in every class description. SelectedIndex should work for a segmented control. Haven't tried it myself though. No; the Cocoa Bindings Reference doesn't catalogue KVO compliance, it lists bindings. In general, controller objects observe model objects, and views observe controllers and models -- you typically don't bind to views. Thus you shouldn't generally expect views' properties to be observable. mmalc ___ 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
Screwy Binding/KVO
Hi, Sorry if this has been posted before; I did a quick scour but might not have used the right keywords (this issue isn't very general). Basically I'm noticing that when I expect KVO observations to be triggered, they aren't. Most likely this is due to my misunderstanding, but I'd like to post a test case here for good measure (I write this last night so bear with me if the comments are a little strange). #import Foundation/Foundation.h #import AppKit/AppKit.h @interface SDObject : NSObject { NSArray *content; } @property (readwrite, retain) NSArray *content; @end int main (int argc, const char * argv[]) { [NSAutoreleasePool new]; SDObject *object = [[SDObject alloc] init]; NSArrayController *controller1 = [[NSArrayController alloc] init]; NSArrayController *controller2 = [[NSArrayController alloc] init]; NSLog(@mark 1); // when this is called, the KVO in SDObject is triggered with an empty array [object bind:@content toObject:controller2 withKeyPath:@arrangedObjects options:nil]; NSLog(@mark 2); [controller2 bind:@contentArray toObject:controller1 withKeyPath:@arrangedObjects options:nil]; NSLog(@mark 3); // these might suppose to trigger it (i thought it would but it doesnt) [controller1 addObject:@test1]; [controller1 addObject:@test2]; // okay i *know* this and the -didChange... should trigger it [controller2 willChangeValueForKey:@arrangedObjects]; // this should too though, right? [controller2 rearrangeObjects]; // (see -willChange... above) [controller2 didChangeValueForKey:@arrangedObjects]; // proving that they all contain the right things NSLog(@%@, [controller2 arrangedObjects]); NSLog(@%@, [object content]); return EXIT_SUCCESS; } @implementation SDObject @synthesize content; + (void) initialize { if (self == [SDObject class]) { [self exposeBinding:@content]; } } - (id) init { self = [super init]; [self addObserver:self forKeyPath:@content options:0 context:NULL]; return self; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { NSLog(@observing keypath [...@] == [...@], keyPath, [self valueForKeyPath :keyPath]); } @end This is the output: *2009-12-11 11:10:02.139 ScrewyKVO[21311:a0f] mark 1* *2009-12-11 11:10:02.515 ScrewyKVO[21311:a0f] observing keypath [content] == [(* *)]* *2009-12-11 11:10:02.516 ScrewyKVO[21311:a0f] mark 2* *2009-12-11 11:10:02.521 ScrewyKVO[21311:a0f] mark 3* *2009-12-11 11:10:02.522 ScrewyKVO[21311:a0f] (* *test1,* *test2* *)* *2009-12-11 11:10:02.522 ScrewyKVO[21311:a0f] (* *test1,* *test2* *)* * * -- Steven Degutis http://www.thoughtfultree.com/ http://www.degutis.org/ ___ 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: Screwy Binding/KVO
On Dec 11, 2009, at 09:10, Steven Degutis wrote: [reformatted to be less annoying] // when this is called, the KVO in SDObject is triggered with an empty array [object bind:@content toObject:controller2 withKeyPath:@arrangedObjects options:nil]; NSLog(@mark 2); Yeah, well, at this point controller2 has no content array, so of course its 'arrangedObjects' is empty. However, this line of code is the heart of your problem, because SDObject has no content binding. It has a content property, but that's not the same as a binding. Compare this with (say) a NSTableView, which has a content binding but no content property. 'bind:toObject:withKeyPath:options:' cannot be used as you are doing, in spite of what the documentation might suggest for the binding parameter: The key path for a property of the receiver previously exposed using the exposeBinding: method. It's not a key path but a binding name. Look at: http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CocoaBindings/Concepts/HowDoBindingsWork.html#//apple_ref/doc/uid/20002373 if you want gory details, but even that document is somewhat inexact in its terminology. It sometimes confuses properties and binding names, or it sometimes uses binds from ... to in the opposite direction from the way we usually say it, or it sometimes confuses the idea that bindings are two-way (they are) with the idea that they're symmetrical (they are not) -- it's a bit hard to tell which. [controller2 bind:@contentArray toObject:controller1 withKeyPath:@arrangedObjects options:nil]; NSLog(@mark 3); // these might suppose to trigger it (i thought it would but it doesnt) [controller1 addObject:@test1]; [controller1 addObject:@test2]; In your sample code, you never gave controller1 any content array. There's nothing to add objects to. // okay i *know* this and the -didChange... should trigger it [controller2 willChangeValueForKey:@arrangedObjects]; Sending willChange/didChange to an object whose implementation you don't control seems like a *terrible* idea. Especially something funky like NSArrayController. // this should too though, right? [controller2 rearrangeObjects]; // (see -willChange... above) [controller2 didChangeValueForKey:@arrangedObjects]; I'm actually surprised you didn't get any exceptions using this code. Did you check the log? ___ 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: Big memory/time consumption in NSTreeController KVO GC
On Dec 8, 2009, at 4:35 PM, Greg Parker wrote: Which OS version is this? 10.6.2 fixed a performance problem with garbage collection and large KVO populations. If you still have trouble in 10.6.2+ then you should file a bug report. On Dec 8, 2009, at 6:38 PM, Rob Keniger wrote: Please see my bug report rdar://7139579 which includes a simple sample project. The performance on Snow Leopard is orders of magnitude slower than in 10.5. As this is on 10.6.2, I’ve filed rdar://problem/7456424, referencing Rob’s report. ...and I should point out that these issues were bad enough for me to completely abandon NSTreeController for my own lightweight tree controller class. I've never looked back, I spent m0re hours struggling with NSTreeController than I care to think about. Considering the other issues I’m having with it, I suspect I’m headed down the same path. For the record, this will be three for three times I’ve tried to use NSTreeController in one of our apps and have been unable to do so. Thank you, Greg and Rob, for your input. Maybe a fix for this can make 10.6.3, with any luck. Best, Benjamin___ 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: Big memory/time consumption in NSTreeController KVO GC
On 9 Dec 2009, at 13:58, Benjamin Rister wrote: Considering the other issues I’m having with it, I suspect I’m headed down the same path. For the record, this will be three for three times I’ve tried to use NSTreeController in one of our apps and have been unable to do so. I seem to spend far too much time fighting with NSTreeController/NSArrayController trying to get real world reliable performance out of them. I think the bindings + KVO technology is great but with GC, at least, it seems easy to contrive a demon. 10.6 especially seems rather toxic. Maybe it's time to back off on those bindings and try a data source. Jonathan___ 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
Big memory/time consumption in NSTreeController KVO GC
I have a NSTreeController displayed via an NSOutlineView. It’s set up to expand items by default as they’re added to the model. This is all on Snow Leopard. When a bunch of items (some thousands) are added and removed from the model, there’s a large memory spike (multi-hundred MB) almost entirely of Malloc 16.50 KB blocks, and the bulk of the CPU time is being spent in libauto. The stack trace of most of the memory allocations is: ... 12 libSystem.B.dylib _dispatch_call_block_and_release 11 libauto.dylib auto_collection_work(Auto::Zone*) 10 libauto.dylib auto_collect_internal(Auto::Zone*, unsigned int) 9 libauto.dylib Auto::Zone::collect(bool, void*, unsigned long long*) 8 libauto.dylib weak_call_callbacks 7 Foundation NSKeyValueObservanceBecameUseless 6 Foundation _NSKeyValueRemoveUselessObservances 5 Foundation _NSKeyValueObservationInfoCreateByCollecting 4 Foundation -[NSKeyValueObservationInfo _initWithObservances:count:] 3 Foundation -[NSConcretePointerArray addPointer:] 2 libauto.dylib auto_assign_weak_reference 1 libauto.dylib weak_register 0 libauto.dylib append_referrer_no_lock(weak_referrer_array_t*, void**, auto_weak_callback_block*) Almost all of the rest are: ... 21 MyProject -[MyModelObject addChild:] 20 Foundation NSKVOInsertObjectAtIndexAndNotify 19 Foundation -[NSObject(NSKeyValueObserverNotification) didChange:valuesAtIndexes:forKey:] 18 Foundation NSKeyValueDidChange 17 AppKit -[NSTreeControllerTreeNode observeValueForKeyPath:ofObject:change:context:] 16 AppKit -[NSTreeControllerTreeNode updateChildNodesForKeyPath:affectedIndexPaths:] 15 AppKit -[NSTreeControllerTreeNode updateChildNodesForKeyPath:affectedIndexPaths:] 14 Foundation -[NSObject(NSKeyValueObserverNotification) didChangeValueForKey:] 13 Foundation NSKeyValueDidChange 12 Foundation -[NSKeyValueNestedProperty object:withObservance:didChangeValueForKeyOrKeys:recurse:forwardingValues:] 11 Foundation -[NSObject(NSKeyValueObserverRegistration) addObserver:forKeyPath:options:context:] 10 Foundation -[NSObject(NSKeyValueObserverRegistration) _addObserver:forProperty:options:context:] 9 Foundation -[NSKeyValueUnnestedProperty object:didAddObservance:recurse:] 8 Foundation -[NSKeyValueNestedProperty object:didAddObservance:recurse:] 7 Foundation -[NSObject(NSKeyValueObserverRegistration) addObserver:forKeyPath:options:context:] 6 Foundation -[NSObject(NSKeyValueObserverRegistration) _addObserver:forProperty:options:context:] 5 Foundation _NSKeyValueObservationInfoCreateByAdding 4 Foundation -[NSKeyValueObservationInfo _initWithObservances:count:] 3 Foundation -[NSConcretePointerArray addPointer:] 2 libauto.dylib auto_assign_weak_reference 1 libauto.dylib weak_register 0 libauto.dylib append_referrer_no_lock(weak_referrer_array_t*, void**, auto_weak_callback_block*) After every item is eventually removed (aside from one remaining one in the root, which was already there at the start), the app is still using 48MB RPRVT. This was 6MB at the start of the process, in this same model state as it ended. heap -guessNonObjects shows most of the memory as non-objects in dictionaries and arrays (e.g. NSCFDictionary[48]), and NSConcretePointerArrays, all in the auto zone. The only references to some of these key function names I could find on the web were in the libauto sources, and no mention at all in mailing lists, so it doesn’t seem like anybody else has posted about this before. Any ideas about why NSTreeController’s KVO is taking up so much memory/CPU with bookkeeping? Any suggestions for working around the problem? Thanks, 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
Re: Big memory/time consumption in NSTreeController KVO GC
Any ideas about why NSTreeController’s KVO is taking up so much memory/CPU with bookkeeping? Any suggestions for working around the problem? I assume that you are using bindings. Looks like a typical KVO notification storm to me. What works well for adding and updating one or two objects can easily turn to sludge for larger object numbers as thousands of KVO notifications are sent. This isn't bookkeeping - its KVO doing what you asked it to do - telling you about every change to your model. Are you adding your nodes to the NSTreeControllers content while bindings are active? If you build your tree separately and then set the NSTreeController content/binding then things should improve drastically. Hope this helps. Jonathan Thanks, 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/jonathan%40mugginsoft.com This email sent to jonat...@mugginsoft.com ___ 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: Big memory/time consumption in NSTreeController KVO GC
On Dec 8, 2009, at 2:44 PM, jonat...@mugginsoft.com wrote: Any ideas about why NSTreeController’s KVO is taking up so much memory/CPU with bookkeeping? Any suggestions for working around the problem? I assume that you are using bindings. Yes. Looks like a typical KVO notification storm to me. What works well for adding and updating one or two objects can easily turn to sludge for larger object numbers as thousands of KVO notifications are sent. This isn't bookkeeping - its KVO doing what you asked it to do - telling you about every change to your model. Well...not quite. There’s nothing about doing this notification that requires allocating hundreds of megabytes of overhead, particularly when the model itself is a fraction of that size, including payload. As I mentioned, these blocks it’s allocating are 16KB each. I can’t fathom what legitimate data you could possibly keep to do this observation that would take up that much space. In addition, if you look at the stack trace, most of the memory allocations are happening in response to NSKeyValueObservanceBecameUseless; thus, it’s happening after all of the actual, real work is done. It’s entirely speculation, but this could be explained by transient KVO stuff not being garbage collected properly, like it’s being kept alive unnecessarily. Also, while I forgot to mention this in the original email, the allocations follow a sawtooth pattern with a period of around 1-2 minutes, rising steadily then suddenly vanishing in an instant. This could support the GC hypothesis, or just be a red herring. Maybe these allocations are being missed by the generational collector for some reason, and are only caught by exhaustive collections? Or maybe some structure/cache/buffer is being periodically flushed, dropping the references? The model objects are gone (obviously, since that’s what triggers the allocations), so it shouldn’t be me keeping them alive. Are you adding your nodes to the NSTreeControllers content while bindings are active? If you build your tree separately and then set the NSTreeController content/binding then things should improve drastically. Unfortunately, this isn’t static content. It’s dynamic, and needs to change in response to external conditions. So the KVO notifications themselves are necessary in this approach, the overhead just seems unreasonable. Best, Benjamin___ 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: Big memory/time consumption in NSTreeController KVO GC
On Dec 8, 2009, at 1:22 PM, Benjamin Rister wrote: Well...not quite. There’s nothing about doing this notification that requires allocating hundreds of megabytes of overhead, particularly when the model itself is a fraction of that size, including payload. As I mentioned, these blocks it’s allocating are 16KB each. I can’t fathom what legitimate data you could possibly keep to do this observation that would take up that much space. In addition, if you look at the stack trace, most of the memory allocations are happening in response to NSKeyValueObservanceBecameUseless; thus, it’s happening after all of the actual, real work is done. Which OS version is this? 10.6.2 fixed a performance problem with garbage collection and large KVO populations. If you still have trouble in 10.6.2+ then you should file a bug report. -- Greg Parker gpar...@apple.com Runtime Wrangler ___ 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: Big memory/time consumption in NSTreeController KVO GC
On 09/12/2009, at 7:35 AM, Greg Parker wrote: Which OS version is this? 10.6.2 fixed a performance problem with garbage collection and large KVO populations. If you still have trouble in 10.6.2+ then you should file a bug report. There are still massive remaining performance issues with NSTreeController/NSArrayController in 10.6 if you have a large number of active bindings. Please see my bug report rdar://7139579 which includes a simple sample project. The performance on Snow Leopard is orders of magnitude slower than in 10.5. All of the problems seem to relate to the private class NSConcretePointerArray and something that it's doing with weak references. That seems to be involved in Benjamin's case and it is definitely the problem in our case based on Shark traces. Specifically, the routines auto_read_weak_reference(), readWeakAt() and objc_read_weak() that appear to be involved in the the -compact method of NSConcretePointerArray are taking up an inordinate amount of CPU time. -- Rob Keniger ___ 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: firstResponder KVO snow leopard crash; bug?
On Nov 18, 2009, at 5:06 PM, Sean McBride wrote: On 11/18/09 9:00 AM, Corbin Dunn said: Oh -- another thing. Does your subclass of NSCollectionView override: (void)viewWillMoveToWindow:(NSWindow *)window { but not call super? If not... call super! Your classes should always call super if it is defined in a superclass, unless you have a good reason to hide the super's behavior. Corbin, This comment caught by eye. As a general principle, I certainly agree with your comment. But I never call super when I override those methods, and I guess I should be doing so. Does NSView's implementation do something or only NSCollectionView? Only NSCollectionView. But, that is a good question; how would one know they should call super? In general, I think people should *always* call super, unless they have some specific reason not to. Assuming that super may or may not do anything is simply an implementation detail -- in the future we may add code that does something. Maybe for this case we should add the declaration to NSCollectionView and state that it overrides the method to do more work. The .NET framework tends to do this to let people know when that happens, and it might be nice for AppKit to do it too. The docs often comment about calling super. In NSView's case, they do for beginDocument, beginPageInRect:atPlacement:, drawRect:, endDocument, viewWillStartLiveResize, etc. but they don't for the viewWillMoveToWindow:. I guess I'm so used to seeing a comment, that if I don't see one, I don't call super. At least one Apple example also doesn't: http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/ EventOverview/MouseTrackingEvents/MouseTrackingEvents.html Should one call super for all the viewWill/Did methods? My opinion is yes. Please log a documentation bug asking to be clarified (you can copy my email into it). corbin ___ 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: firstResponder KVO snow leopard crash; bug?
On Nov 18, 2009, at 5:28 PM, Aaron Clarke wrote: On Nov 18, 2009, at 12:00 , Corbin Dunn wrote: On Nov 17, 2009, at 1:04 PM, Aaron Clarke wrote: We have an application that runs fine on leopard (10.5) but occasionally crashes on snow leopard (10.6) when closing an NSWindow. Here is the backtrace for the crash: Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_PROTECTION_FAILURE at address: 0x 0x976e691b in objc_msgSend () (gdb) bt #0 0x976e691b in objc_msgSend () #1 0x197142d0 in ?? () #2 0x9031e88e in NSKeyValuePushPendingNotificationPerThread () #3 0x9031e224 in NSKeyValueWillChange () #4 0x9030350b in -[NSObject(NSKeyValueObserverNotification) willChangeValueForKey:] () #5 0x90327cfe in _NSSetObjectValueAndNotify () #6 0x92745fb8 in -[NSWindow makeFirstResponder:] () ... Even if it doesn't crash, closing the NSWindow always results in the following error message. An instance 0x11b75230 of class MyWindow 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. Here's the current observation info: NSKeyValueObservationInfo 0x19408190 ( NSKeyValueObservance 0x194233d0: Observer: 0x463afa0, Key path: firstResponder, Options: New: YES, Old: NO, Prior: NO Context: 0x0, Property: 0x4453e60 NSKeyValueObservance 0x1ab6ad40: Observer: 0x19427a80, Key path: firstResponder, Options: New: YES, Old: NO, Prior: NO Context: 0x0, Property: 0x4453e60 ) I looked at what the observer object's class is, and it's a subclass of NSCollectionView. We do not explicitly setup a KVO relationship for firstResponder. I also noticed that the Application Kit Release Notes for Snow Leopard mention that firstResponder is KVO-compliant, which makes me believe this is something new in Snow Leopard. All this information makes me believe this is potentially a bug in Application Kit for 10.6. Maybe we setup an NSCollectionView incorrectly or I'm misinterpreting this information? Oh -- another thing. Does your subclass of NSCollectionView override: (void)viewWillMoveToWindow:(NSWindow *)window { but not call super? If not... call super! Your classes should always call super if it is defined in a superclass, unless you have a good reason to hide the super's behavior. corbin This was the problem, thank you. This is a difficult bug to find in code someone else wrote. This makes me almost wish there was a gcc flag for it (-Woverride-no-super). FWIW, this is a compatibility problem we (AppKit) try to avoid. An update to the OS shouldn't break one's app. Right now it is (obviously) too late to change AppKit for SnowLeopard, but please do log a bug so we can do something about it (it will probably amount to a tech note or release note or documentation change for NSCollectionView). corbin ___ 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: firstResponder KVO snow leopard crash; bug?
On Nov 17, 2009, at 2:04 PM, Aaron Clarke wrote: Even if it doesn't crash, closing the NSWindow always results in the following error message. An instance 0x11b75230 of class MyWindow 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. Here's the current observation info: NSKeyValueObservationInfo 0x19408190 ( NSKeyValueObservance 0x194233d0: Observer: 0x463afa0, Key path: firstResponder, Options: New: YES, Old: NO, Prior: NO Context: 0x0, Property: 0x4453e60 NSKeyValueObservance 0x1ab6ad40: Observer: 0x19427a80, Key path: firstResponder, Options: New: YES, Old: NO, Prior: NO Context: 0x0, Property: 0x4453e60 ) Do you have release when closed checked for the window? If so, what happens when you uncheck it? HTH, Keary Suska Esoteritech, Inc. Demystifying technology for your home or business ___ 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: firstResponder KVO snow leopard crash; bug?
On Nov 17, 2009, at 1:04 PM, Aaron Clarke wrote: We have an application that runs fine on leopard (10.5) but occasionally crashes on snow leopard (10.6) when closing an NSWindow. Here is the backtrace for the crash: Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_PROTECTION_FAILURE at address: 0x 0x976e691b in objc_msgSend () (gdb) bt #0 0x976e691b in objc_msgSend () #1 0x197142d0 in ?? () #2 0x9031e88e in NSKeyValuePushPendingNotificationPerThread () #3 0x9031e224 in NSKeyValueWillChange () #4 0x9030350b in -[NSObject(NSKeyValueObserverNotification) willChangeValueForKey:] () #5 0x90327cfe in _NSSetObjectValueAndNotify () #6 0x92745fb8 in -[NSWindow makeFirstResponder:] () ... Even if it doesn't crash, closing the NSWindow always results in the following error message. An instance 0x11b75230 of class MyWindow 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. Here's the current observation info: NSKeyValueObservationInfo 0x19408190 ( NSKeyValueObservance 0x194233d0: Observer: 0x463afa0, Key path: firstResponder, Options: New: YES, Old: NO, Prior: NO Context: 0x0, Property: 0x4453e60 NSKeyValueObservance 0x1ab6ad40: Observer: 0x19427a80, Key path: firstResponder, Options: New: YES, Old: NO, Prior: NO Context: 0x0, Property: 0x4453e60 ) I looked at what the observer object's class is, and it's a subclass of NSCollectionView. We do not explicitly setup a KVO relationship for firstResponder. I also noticed that the Application Kit Release Notes for Snow Leopard mention that firstResponder is KVO-compliant, which makes me believe this is something new in Snow Leopard. All this information makes me believe this is potentially a bug in Application Kit for 10.6. Maybe we setup an NSCollectionView incorrectly or I'm misinterpreting this information? Your window might be doing something strange, and causing notifications to be suppressed some how. What code does MyWindow have in it? corbin ___ 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: firstResponder KVO snow leopard crash; bug?
On Nov 17, 2009, at 1:04 PM, Aaron Clarke wrote: We have an application that runs fine on leopard (10.5) but occasionally crashes on snow leopard (10.6) when closing an NSWindow. Here is the backtrace for the crash: Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_PROTECTION_FAILURE at address: 0x 0x976e691b in objc_msgSend () (gdb) bt #0 0x976e691b in objc_msgSend () #1 0x197142d0 in ?? () #2 0x9031e88e in NSKeyValuePushPendingNotificationPerThread () #3 0x9031e224 in NSKeyValueWillChange () #4 0x9030350b in -[NSObject(NSKeyValueObserverNotification) willChangeValueForKey:] () #5 0x90327cfe in _NSSetObjectValueAndNotify () #6 0x92745fb8 in -[NSWindow makeFirstResponder:] () ... Even if it doesn't crash, closing the NSWindow always results in the following error message. An instance 0x11b75230 of class MyWindow 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. Here's the current observation info: NSKeyValueObservationInfo 0x19408190 ( NSKeyValueObservance 0x194233d0: Observer: 0x463afa0, Key path: firstResponder, Options: New: YES, Old: NO, Prior: NO Context: 0x0, Property: 0x4453e60 NSKeyValueObservance 0x1ab6ad40: Observer: 0x19427a80, Key path: firstResponder, Options: New: YES, Old: NO, Prior: NO Context: 0x0, Property: 0x4453e60 ) I looked at what the observer object's class is, and it's a subclass of NSCollectionView. We do not explicitly setup a KVO relationship for firstResponder. I also noticed that the Application Kit Release Notes for Snow Leopard mention that firstResponder is KVO-compliant, which makes me believe this is something new in Snow Leopard. All this information makes me believe this is potentially a bug in Application Kit for 10.6. Maybe we setup an NSCollectionView incorrectly or I'm misinterpreting this information? Oh -- another thing. Does your subclass of NSCollectionView override: (void)viewWillMoveToWindow:(NSWindow *)window { but not call super? If not... call super! Your classes should always call super if it is defined in a superclass, unless you have a good reason to hide the super's behavior. corbin ___ 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: firstResponder KVO snow leopard crash; bug?
On 11/18/09 9:00 AM, Corbin Dunn said: Oh -- another thing. Does your subclass of NSCollectionView override: (void)viewWillMoveToWindow:(NSWindow *)window { but not call super? If not... call super! Your classes should always call super if it is defined in a superclass, unless you have a good reason to hide the super's behavior. Corbin, This comment caught by eye. As a general principle, I certainly agree with your comment. But I never call super when I override those methods, and I guess I should be doing so. Does NSView's implementation do something or only NSCollectionView? The docs often comment about calling super. In NSView's case, they do for beginDocument, beginPageInRect:atPlacement:, drawRect:, endDocument, viewWillStartLiveResize, etc. but they don't for the viewWillMoveToWindow:. I guess I'm so used to seeing a comment, that if I don't see one, I don't call super. At least one Apple example also doesn't: http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/ EventOverview/MouseTrackingEvents/MouseTrackingEvents.html Should one call super for all the viewWill/Did methods? Thanks, -- Sean McBride, B. Eng s...@rogue-research.com Rogue Researchwww.rogue-research.com Mac Software Developer Montréal, Québec, Canada ___ 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: firstResponder KVO snow leopard crash; bug?
On Nov 18, 2009, at 12:00 , Corbin Dunn wrote: On Nov 17, 2009, at 1:04 PM, Aaron Clarke wrote: We have an application that runs fine on leopard (10.5) but occasionally crashes on snow leopard (10.6) when closing an NSWindow. Here is the backtrace for the crash: Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_PROTECTION_FAILURE at address: 0x 0x976e691b in objc_msgSend () (gdb) bt #0 0x976e691b in objc_msgSend () #1 0x197142d0 in ?? () #2 0x9031e88e in NSKeyValuePushPendingNotificationPerThread () #3 0x9031e224 in NSKeyValueWillChange () #4 0x9030350b in -[NSObject(NSKeyValueObserverNotification) willChangeValueForKey:] () #5 0x90327cfe in _NSSetObjectValueAndNotify () #6 0x92745fb8 in -[NSWindow makeFirstResponder:] () ... Even if it doesn't crash, closing the NSWindow always results in the following error message. An instance 0x11b75230 of class MyWindow 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. Here's the current observation info: NSKeyValueObservationInfo 0x19408190 ( NSKeyValueObservance 0x194233d0: Observer: 0x463afa0, Key path: firstResponder, Options: New: YES, Old: NO, Prior: NO Context: 0x0, Property: 0x4453e60 NSKeyValueObservance 0x1ab6ad40: Observer: 0x19427a80, Key path: firstResponder, Options: New: YES, Old: NO, Prior: NO Context: 0x0, Property: 0x4453e60 ) I looked at what the observer object's class is, and it's a subclass of NSCollectionView. We do not explicitly setup a KVO relationship for firstResponder. I also noticed that the Application Kit Release Notes for Snow Leopard mention that firstResponder is KVO-compliant, which makes me believe this is something new in Snow Leopard. All this information makes me believe this is potentially a bug in Application Kit for 10.6. Maybe we setup an NSCollectionView incorrectly or I'm misinterpreting this information? Oh -- another thing. Does your subclass of NSCollectionView override: (void)viewWillMoveToWindow:(NSWindow *)window { but not call super? If not... call super! Your classes should always call super if it is defined in a superclass, unless you have a good reason to hide the super's behavior. corbin This was the problem, thank you. This is a difficult bug to find in code someone else wrote. This makes me almost wish there was a gcc flag for it (-Woverride-no-super). -Aaron ___ 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: firstResponder KVO snow leopard crash; bug?
Aaron Clarke (clark...@gmail.com) on 2009-11-18 8:28 PM said: Oh -- another thing. Does your subclass of NSCollectionView override: (void)viewWillMoveToWindow:(NSWindow *)window { but not call super? If not... call super! Your classes should always call super if it is defined in a superclass, unless you have a good reason to hide the super's behavior. corbin This was the problem, thank you. This is a difficult bug to find in code someone else wrote. This makes me almost wish there was a gcc flag for it (-Woverride-no-super). You will get such a warning if you fail to call super in dealloc and finalize. Expanding that to more methods should be possible I guess... maybe a job for the clang static analyzer. Do file a bug. Sean ___ 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
firstResponder KVO snow leopard crash; bug?
We have an application that runs fine on leopard (10.5) but occasionally crashes on snow leopard (10.6) when closing an NSWindow. Here is the backtrace for the crash: Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_PROTECTION_FAILURE at address: 0x 0x976e691b in objc_msgSend () (gdb) bt #0 0x976e691b in objc_msgSend () #1 0x197142d0 in ?? () #2 0x9031e88e in NSKeyValuePushPendingNotificationPerThread () #3 0x9031e224 in NSKeyValueWillChange () #4 0x9030350b in -[NSObject(NSKeyValueObserverNotification) willChangeValueForKey:] () #5 0x90327cfe in _NSSetObjectValueAndNotify () #6 0x92745fb8 in -[NSWindow makeFirstResponder:] () ... Even if it doesn't crash, closing the NSWindow always results in the following error message. An instance 0x11b75230 of class MyWindow 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. Here's the current observation info: NSKeyValueObservationInfo 0x19408190 ( NSKeyValueObservance 0x194233d0: Observer: 0x463afa0, Key path: firstResponder, Options: New: YES, Old: NO, Prior: NO Context: 0x0, Property: 0x4453e60 NSKeyValueObservance 0x1ab6ad40: Observer: 0x19427a80, Key path: firstResponder, Options: New: YES, Old: NO, Prior: NO Context: 0x0, Property: 0x4453e60 ) I looked at what the observer object's class is, and it's a subclass of NSCollectionView. We do not explicitly setup a KVO relationship for firstResponder. I also noticed that the Application Kit Release Notes for Snow Leopard mention that firstResponder is KVO-compliant, which makes me believe this is something new in Snow Leopard. All this information makes me believe this is potentially a bug in Application Kit for 10.6. Maybe we setup an NSCollectionView incorrectly or I'm misinterpreting this information? -Aaron ___ 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
KVO cross dependencies
Hi all, I have sevral objects of different kind that observe values on each other. Now, when the objects are being released, I get an exception from the KVO stuff telling me that an object is being deallocated while still observed. And that's justified. Yet, the problem is in whatever way, order I deallocate the objects that will always happen because of these cross observations. Therefore what I should do is tell everyone that's observing an object to remove them as observers. But how can I get a list of all observed keys and the observers? Regards. PS: I thought about setting the observation info to nil but I guess this is a one way ticket to a segfault. ___ 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: KVO cross dependencies
One option - use Garbage Collection under Snow Leopard, it does it all for you. If you can't do that. I assume, from the fact that your observed objects are being released at all that the observing objects are not retaining them (or keeping strong references if you are using Garbage Collection), if you had them retained by the observing object then they wouldn't be getting dealloced. If the observations are in a tree, then you could have the observers retain the objects they are observing and unobserve them as they release them, then you'll never have the issue of an object with registered observers being deallocated. If, however you can't do that, because the objects all observe each other, you'll get retain cycles (again assuming you are not using GC), so you cannot retain and need to tell the observing object to remove its observations on the observed object before it dies. One way to do that is to have another property on the objects, something like canBeObserved, and have all your observers observe that property *as well* as other observations they have. In your dealloc method, right at the start of it, flip that property to NO and all your observers will be told you are no longer observable, they are then responsible for removing their observations. This happens synchronously, so by the time you continue with dealloc, nobody is observing you any more. We had a thread about this a few months ago where we discussed whether it was legitimate to do this in dealloc and discussing a note in the Snow Leopard release notes about that message and I believe that most people were satisfied that it was a supported thing to do. Note that even if you do this, under 10.5 you will STILL get that warning message (not an exception) because it was emitted at the start of dealloc() before you had a chance to tell your observers to stop observing, that was what the release note addressed. I don't think there is a documented way of finding out who is observing you and what they are observing. On 13-Nov-2009, at 9:43 PM, Half Activist wrote: Hi all, I have sevral objects of different kind that observe values on each other. Now, when the objects are being released, I get an exception from the KVO stuff telling me that an object is being deallocated while still observed. And that's justified. Yet, the problem is in whatever way, order I deallocate the objects that will always happen because of these cross observations. Therefore what I should do is tell everyone that's observing an object to remove them as observers. But how can I get a list of all observed keys and the observers? Regards. PS: I thought about setting the observation info to nil but I guess this is a one way ticket to a segfault. ___ 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/rols%40rols.org This email sent to r...@rols.org ___ 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
Programmatic Binding KVC KVO
I have a managed object context with two attached NSObjectControllers in entity mode. Both controllers control the same entity. managed object model nib 1 controller user interface bind in interface builder nib 2 controller user interface (custom view) bind in code programmatically Nib 1 works. Entity changes produce by the user interface show up in the managed object model and in the custom view found in nib 2. Nib 2 only partly works. Changes made in the custom view do not show up in the managed object model or in the user interface found in nib 1. When establishing a binding programmatically do you also need to setup key value observing? I thought a binding was bi-directional and included both key value coding and observing. Richard ___ 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: Programmatic Binding KVC KVO
On Nov 4, 2009, at 6:04 AM, Richard Somers rsomers.li...@infowest.com wrote: I have a managed object context with two attached NSObjectControllers in entity mode. Both controllers control the same entity. Important: do you really mean entity, or do you mean managed object? managed object model nib 1 controller user interface bind in interface builder nib 2 controller user interface (custom view) bind in code programmatically You need to describe precisely what you've done in both cases, which includes posting your code. You also make no mention of what managed object context your controllers are hooked up to. Nib 1 works. Entity changes produce by the user interface show up in the managed object model and in the custom view found in nib 2. Here, you mean to say that managed object property changes show up in your managed object context. Nib 2 only partly works. Changes made in the custom view do not show up in the managed object model or in the user interface found in nib 1. So now we also need to see your custom view code. When establishing a binding programmatically do you also need to setup key value observing? I thought a binding was bi-directional and included both key value coding and observing. No, bindings are not directional, and only do whatever you tell them to. NSObject's implementation of -bind:toObject:… starts observing the specified keypath, and its implementation of - observeValueForKeyPath:… attempts to use KVC to set a property with the same name as the binding. 99% of the time you're going to provide a custom implementation of both of these methods, and not calling super's implementation. Neither of these scenarios handles the reverse case. --Kyle Sluder___ 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: Programmatic Binding KVC KVO
On Nov 4, 2009, at 9:40 AM, Kyle Sluder wrote: Nib 2 only partly works. Changes made in the custom view do not show up in the managed object model or in the user interface found in nib 1. So now we also need to see your custom view code. Here is the code for nib 2 which only partly works. Changes to the model property num are reflected in the custom view but changes to the num property in the custom view do not show up in the model. All code in the custom view that touch the num property use the accessor methods. The controller in the nib is in entity mode and bound to File's Owner (MyDocument) managed object context. @interface MyView : NSView { double num; } @end @implementation MyView - (double)num { return num; } - (void)setnum:(double)newNum { [self willChangeValueForKey:@num]; num = newNum; [self didChangeValueForKey:@num]; } @end @interface MyDocument : NSPersistentDocument { IBOutlet MyView *myView; IBOutlet NSObjectController *controller; } @end @implementation MyDocument - (void)windowControllerDidLoadNib:(NSWindowController *)windowController { [super windowControllerDidLoadNib:windowController]; [myView bind:@num toObject:controller withKeyPath:@selection.num options:nil]; } @end Thanks for looking at this. Richard ___ 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: Programmatic Binding KVC KVO
On Wed, Nov 4, 2009 at 12:17 PM, Richard Somers rsomers.li...@infowest.com wrote: All code in the custom view that touch the num property use the accessor methods. The controller in the nib is in entity mode and bound to File's Owner (MyDocument) managed object context. Okay, but as I said before, the default NSObject bindings implementation only set up KVO in one direction. If you call -[myView bind:@num toObject:myController withKeyPath:@someModelKeyPath options:0], KVO will only occur from [myController].someModelKeyPath -- [myView].num. NSObject doesn't (and can't) also set up the reverse direction. @interface MyView : NSView { double num; } @end @implementation MyView - (double)num { return num; } - (void)setnum:(double)newNum This is not a KVC-compliant accessor for the num property. It needs to be named -setNum:. { [self willChangeValueForKey:@num]; Do not do this if you have not overridden -automaticallyNotifiesObserversForKey: to return NO for the num key. [myView bind:@num toObject:controller withKeyPath:@selection.num options:nil]; This invokes the default implementation of -bind:toObject:withKeyPath:options:, which takes care of the model - view communication. You now need to take care of the view - model communication. As described in the User Updates a Value in the User Interface section of the Cocoa Bindings Programming Topics, you can call -setValue:forKeyPath: on the toObject and withKeyPath arguments of the original binding (you can get this information by calling -infoForBinding). Or you might have some custom logic that informs the controller/model of the change in a different way. --Kyle Sluder ___ 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: Programmatic Binding KVC KVO
On Nov 4, 2009, at 3:17 PM, Richard Somers wrote: @interface MyView : NSView { double num; } @end @implementation MyView - (double)num { return num; } - (void)setnum:(double)newNum { [self willChangeValueForKey:@num]; num = newNum; [self didChangeValueForKey:@num]; } @end When the view changes num, it need to push the change to the bound model objects. See mmalc’s Graphics Bindings sample: http://homepage.mac.com/mmalc/CocoaExamples/controllers.html - Jim ___ 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: Programmatic Binding KVC KVO
On Nov 4, 2009, at 2:31 PM, Kyle Sluder wrote: This invokes the default implementation of - bind:toObject:withKeyPath:options:, which takes care of the model - view communication. You now need to take care of the view - model communication. As described in the User Updates a Value in the User Interface section of the Cocoa Bindings Programming Topics, you can call -setValue:forKeyPath: on the toObject and withKeyPath arguments of the original binding (you can get this information by calling - infoForBinding). Or you might have some custom logic that informs the controller/model of the change in a different way. On Nov 4, 2009, at 2:34 PM, Jim Correia wrote: When the view changes num, it need to push the change to the bound model objects. See mmalc’s Graphics Bindings sample: http://homepage.mac.com/mmalc/CocoaExamples/controllers.html Sometimes Cocoa can be overwhelming. This will help. Thank you so much. :) Richard ___ 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: Programmatic Binding KVC KVO
On 05/11/2009, at 8:42 AM, Richard Somers wrote: See mmalc’s Graphics Bindings sample: http://homepage.mac.com/mmalc/CocoaExamples/controllers.html Sometimes Cocoa can be overwhelming. This will help. Thank you so much. :) You might also find this blog post very helpful: http://www.tomdalling.com/cocoa/implementing-your-own-cocoa-bindings -- Rob Keniger ___ 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: Programmatic Binding KVC KVO
On Nov 4, 2009, at 5:20 pm, Rob Keniger wrote: See mmalc’s Graphics Bindings sample: http://homepage.mac.com/mmalc/CocoaExamples/controllers.html Sometimes Cocoa can be overwhelming. This will help. Thank you so much. :) You might also find this blog post very helpful: http://www.tomdalling.com/cocoa/implementing-your-own-cocoa-bindings Rather more relevant, the documentation pretty-nuch explains the simpler of the two bound views in the Graphics Bindings example: http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CocoaBindings/Concepts/HowDoBindingsWork.html#//apple_ref/doc/uid/20002373 Sample code just for the joystick view is also available: http://developer.apple.com/mac/library/samplecode/BindingsJoystick/ mmalc ___ 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: Core Data design question: receiving KVO notifications of partially mutated objects
On 11/2/09 12:58 PM, Ben Trumbull said: This doesn't really have anything to do with Core Data. However, for NSManagedObject, Core Data already provides the change coalescing and NSNotifications for you. You can respond within NSManagedObjectContextObjectsDidChangeNotification instead. So I read the various archive posts about that notification and played with it a little. I can see it being handy, especially for added and removed objects. The big shortcoming, in my situation anyway, is that it does not seem to provide me with the keys that changed (in the NSUpdatedObjectsKey case). Unless I'm missing something? Thanks, -- Sean McBride, B. Eng s...@rogue-research.com Rogue Researchwww.rogue-research.com Mac Software Developer Montréal, Québec, Canada ___ 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: Core Data design question: receiving KVO notifications of partially mutated objects
What is considered best practice when it comes to mutating many properties of a managed object, specifically with regard to KVO observers getting notified before all mutations are finished? This is a problem intrinsic to the design of KVO. KVO is all about fine grained per property notifications. It's very well suited to that. However, it's common for complex objects to be in an intermediate state during a KVO notification. There's no better notion of cross-property coherence than refactoring into a different property object that encapsulates everything. Let's say I have an Rectangle object. It has properties: colour, width, height. Imagine some controller observing all these properties, perhaps to trigger a redraw. If I do: [rect setColour:...]; [rect setWidth:...]; [rect setHeight:...]; In this example, the best KVO can do is work with a colored rectangle object that in turn is the 1 property you work with here. So, this would be an example of a granularity of notification that works better with NSNotificationCenter This is short and readable. But observers will be notified after each setter. yup This could be a problem if intermediate states are not self- consistent and could also lead to unnecessary redrawing. And many other performance issues if observers recalculate things too aggressively. In the general case, I might not even know who is observing. Well, that's the point of the notification pattern. I guess it's safer to create a setColour:width:height: method in my NSManagedObject subclass that does: [self willAccessValueForKey:@colour]; [self willAccessValueForKey:@width]; [self setPrimitiveColour:...]; [self setPrimitiveWidth:...]; [self didAccessValueForKey:@width]; [self didAccessValueForKey:@colour]; Is this what I should be doing? Generally, no. (setting aside, the calls should be to willChangeValueForKey:, btw) If your issue is that drawing or recalculation is occurring too frequently after KVO changes, you can consider coalescing and deferring the observers' actions instead of performing them synchronously. This can be valuable even for less complex KVO issues. You could also refactor the 3 properties into 1 object. Or use an NSNotification instead of KVO to adjust the granularity of notifications to better suit your drawing code. This doesn't really have anything to do with Core Data. However, for NSManagedObject, Core Data already provides the change coalescing and NSNotifications for you. You can respond within NSManagedObjectContextObjectsDidChangeNotification instead. - Ben ___ 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: Core Data design question: receiving KVO notifications of partially mutated objects
Graham, Thanks for the detailed reply! I'd say you're going down the wrong path there. Agreed, hence my post. :) Set each property individually. Yes, it will trigger a notification for each one - doesn't or shouldn't matter, and unless you can show it causes a performance problem, shouldn't be a cause for worry on that score. It won't cause multiple redrawing, because even if each one posted a -setNeedsDisplayInRect:, the actual drawing will not get processed until the next update cycle and invalidating the same area three times still only results in one redraw, by which time all the properties will be set. Drawing performance is not an issue here (unless you are bypassing the update mechanism and forcing the drawing on a notification, but that's a different wrong, so you're not doing that, are you?). My 'Rectangle' object with colour, width, and height attributes was an example of course. I should probably have clarified that or just not have used drawing as an example. You are right about the whole redraw mechanism of course, and my drawing is in fact fine, and I'm not doing anything mischievous there. The question of whether the separate notifications lead to an invalid intermediate state is a more reasonable problem to consider, but it normally shouldn't matter either. Normally KVO will be used to update your UI and/or maintain undo. You mention Core Data so that will handle undo for you but even if you were doing that yourself it shouldn't matter. Undo will record each property change and group them, so you end up with one undo that undoes all three property changes. Any UI that represents each property will also update all at once (or appear to) because the drawing update cycle won't actually show changes until the update runs and flushes the changes to the backing store. In general, I've found things do indeed work that way, and they work well. As a general rule you can and should treat each property in isolation. Even if some command sets several at once, you should find that it all works correctly unless you've gone out of your way to depend on some property state always being paired with some other property state, in which case you should probably make that state pair a separate property. I think as a general rule the approach you're proposing is unnecessary and untidy. I'm starting to think perhaps the root of my problem is that I am using KVO in my controller layer to do things that should be done in my model layer. Sometimes the creation of one ManagedObject, say type 'Foo', requires that: - several other ManagedObjects be created and related. - several existing ManagedObjects be found and related. Where is the right place to do such a thing? Currently, I often do it by KVO observing, in my NSDocument, the creation of new Foos. When I detect new ones, I'll perform some fetches, create new objects, relate them appropriately, etc. (In the past, I tried doing such things inside Foo's awakeFromInsert but I discovered that performing a fetch from that function leads to various problems.) Thanks, -- Sean McBride, B. Eng s...@rogue-research.com Rogue Researchwww.rogue-research.com Mac Software Developer Montréal, Québec, Canada ___ 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: Core Data design question: receiving KVO notifications of partially mutated objects
On 11/2/09 12:58 PM, Ben Trumbull said: What is considered best practice when it comes to mutating many properties of a managed object, specifically with regard to KVO observers getting notified before all mutations are finished? This is a problem intrinsic to the design of KVO. KVO is all about fine grained per property notifications. It's very well suited to that. However, it's common for complex objects to be in an intermediate state during a KVO notification. There's no better notion of cross-property coherence than refactoring into a different property object that encapsulates everything. Let's say I have an Rectangle object. It has properties: colour, width, height. Imagine some controller observing all these properties, perhaps to trigger a redraw. If I do: [rect setColour:...]; [rect setWidth:...]; [rect setHeight:...]; In this example, the best KVO can do is work with a colored rectangle object that in turn is the 1 property you work with here. So, this would be an example of a granularity of notification that works better with NSNotificationCenter This is short and readable. But observers will be notified after each setter. yup This could be a problem if intermediate states are not self- consistent and could also lead to unnecessary redrawing. And many other performance issues if observers recalculate things too aggressively. In the general case, I might not even know who is observing. Well, that's the point of the notification pattern. I guess it's safer to create a setColour:width:height: method in my NSManagedObject subclass that does: [self willAccessValueForKey:@colour]; [self willAccessValueForKey:@width]; [self setPrimitiveColour:...]; [self setPrimitiveWidth:...]; [self didAccessValueForKey:@width]; [self didAccessValueForKey:@colour]; Is this what I should be doing? Generally, no. (setting aside, the calls should be to willChangeValueForKey:, btw) Ben, Thanks for all the above comments, they have each connected a few dots in my mind. If your issue is that drawing or recalculation is occurring too frequently after KVO changes, you can consider coalescing and deferring the observers' actions instead of performing them synchronously. This can be valuable even for less complex KVO issues. You could also refactor the 3 properties into 1 object. Alas, that would require 1) persistent store migration (painful on 10.5) and 2) I find it very handy to be able to bind 'colour' to a colourwell and 'width' and 'height' to text fields. Perhaps I have bent my model too much in favour of my UI also. :) But anyway, this 'Rectangle' object was just an example. My real app is a bit harder to explain. Or use an NSNotification instead of KVO to adjust the granularity of notifications to better suit your drawing code. This doesn't really have anything to do with Core Data. However, for NSManagedObject, Core Data already provides the change coalescing and NSNotifications for you. You can respond within NSManagedObjectContextObjectsDidChangeNotification instead. Perhaps NSManagedObjectContextObjectsDidChangeNotification is the thing I have overlooked! I currently use it almost nowhere but have tonnes and tonnes of KVO observing going on. I'll have to RTFM on NSManagedObjectC ontextObjectsDidChangeNotification. Questions that pop to mind though: is it safe for me to fetch? to create/delete/mutate ManagedObjects? Ultimately, my recent problem with 'dangling reference to an invalid object' made me realise I probably have some design problems, which I can't quite put my finger on. I'm pretty sure I'm misusing/abusing KVO however. Thanks, -- Sean McBride, B. Eng s...@rogue-research.com Rogue Researchwww.rogue-research.com Mac Software Developer Montréal, Québec, Canada ___ 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: Core Data design question: receiving KVO notifications of partially mutated objects
If your issue is that drawing or recalculation is occurring too frequently after KVO changes, you can consider coalescing and deferring the observers' actions instead of performing them synchronously. This can be valuable even for less complex KVO issues. You could also refactor the 3 properties into 1 object. Alas, that would require 1) persistent store migration (painful on 10.5) and 2) I find it very handy to be able to bind 'colour' to a colourwell and 'width' and 'height' to text fields. Perhaps I have bent my model too much in favour of my UI also. :) But anyway, this 'Rectangle' object was just an example. My real app is a bit harder to explain. Or use an NSNotification instead of KVO to adjust the granularity of notifications to better suit your drawing code. This doesn't really have anything to do with Core Data. However, for NSManagedObject, Core Data already provides the change coalescing and NSNotifications for you. You can respond within NSManagedObjectContextObjectsDidChangeNotification instead. Perhaps NSManagedObjectContextObjectsDidChangeNotification is the thing I have overlooked! I currently use it almost nowhere but have tonnes and tonnes of KVO observing going on. I'll have to RTFM on NSManagedObjectC ontextObjectsDidChangeNotification. Questions that pop to mind though: is it safe for me to fetch? to create/delete/mutate ManagedObjects? I'd recommend performing a selector after delay 0. You can inspect the objects and decide what you want to do with them. The notification is posted from within the change tracking code, so making changes could possibly result in them getting caught in between 1 user event and the next. - Ben ___ 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
Core Data design question: receiving KVO notifications of partially mutated objects
Hi all, What is considered best practice when it comes to mutating many properties of a managed object, specifically with regard to KVO observers getting notified before all mutations are finished? Let's say I have an Rectangle object. It has properties: colour, width, height. Imagine some controller observing all these properties, perhaps to trigger a redraw. If I do: [rect setColour:...]; [rect setWidth:...]; [rect setHeight:...]; This is short and readable. But observers will be notified after each setter. This could be a problem if intermediate states are not self- consistent and could also lead to unnecessary redrawing. In the general case, I might not even know who is observing. I guess it's safer to create a setColour:width:height: method in my NSManagedObject subclass that does: [self willAccessValueForKey:@colour]; [self willAccessValueForKey:@width]; [self setPrimitiveColour:...]; [self setPrimitiveWidth:...]; [self didAccessValueForKey:@width]; [self didAccessValueForKey:@colour]; Is this what I should be doing? I can see it getting ugly with more than 3 or so properties... Thanks, -- Sean McBride, B. Eng s...@rogue-research.com Rogue Researchwww.rogue-research.com Mac Software Developer Montréal, Québec, Canada ___ 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: Core Data design question: receiving KVO notifications of partially mutated objects
On 31/10/2009, at 9:01 AM, Sean McBride wrote: Hi all, What is considered best practice when it comes to mutating many properties of a managed object, specifically with regard to KVO observers getting notified before all mutations are finished? In situations like these I personally tend to avoid KVO. It's too noisy and in some cases incurs too much of a performance overhead. But, I have a solution which I describe below. Let's say I have an Rectangle object. It has properties: colour, width, height. Imagine some controller observing all these properties, perhaps to trigger a redraw. If I do: [rect setColour:...]; [rect setWidth:...]; [rect setHeight:...]; This is short and readable. But observers will be notified after each setter. This could be a problem if intermediate states are not self- consistent and could also lead to unnecessary redrawing. In the general case, I might not even know who is observing. I guess it's safer to create a setColour:width:height: method in my NSManagedObject subclass that does: [self willAccessValueForKey:@colour]; [self willAccessValueForKey:@width]; [self setPrimitiveColour:...]; [self setPrimitiveWidth:...]; [self didAccessValueForKey:@width]; [self didAccessValueForKey:@colour]; Is this what I should be doing? I can see it getting ugly with more than 3 or so properties... Perhaps make a property that represents the state of the value these dependent properties contribute to? For example, is it possible to have a requires redraw property of the Rectangle? You could simply change the value of that property (in the overridden setColor:, setWidth:, setLength: methods *sigh*) to indicate the Rectangle object requires a redraw? Then, when a third party wants the value of the dependent property, you can recalculate it. In the given example, the rectangle will only re-draw when it's needed. Just a few ideas, not sure if they're of any help. They're not coming from a Core Data perspective either, just a general one - but I wouldn't expect it to be much different? Kiel ___ 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: Core Data design question: receiving KVO notifications of partially mutated objects
Hi Sean, I'd say you're going down the wrong path there. Set each property individually. Yes, it will trigger a notification for each one - doesn't or shouldn't matter, and unless you can show it causes a performance problem, shouldn't be a cause for worry on that score. It won't cause multiple redrawing, because even if each one posted a -setNeedsDisplayInRect:, the actual drawing will not get processed until the next update cycle and invalidating the same area three times still only results in one redraw, by which time all the properties will be set. Drawing performance is not an issue here (unless you are bypassing the update mechanism and forcing the drawing on a notification, but that's a different wrong, so you're not doing that, are you?). The question of whether the separate notifications lead to an invalid intermediate state is a more reasonable problem to consider, but it normally shouldn't matter either. Normally KVO will be used to update your UI and/or maintain undo. You mention Core Data so that will handle undo for you but even if you were doing that yourself it shouldn't matter. Undo will record each property change and group them, so you end up with one undo that undoes all three property changes. Any UI that represents each property will also update all at once (or appear to) because the drawing update cycle won't actually show changes until the update runs and flushes the changes to the backing store. As a general rule you can and should treat each property in isolation. Even if some command sets several at once, you should find that it all works correctly unless you've gone out of your way to depend on some property state always being paired with some other property state, in which case you should probably make that state pair a separate property. I think as a general rule the approach you're proposing is unnecessary and untidy. --Graham On 31/10/2009, at 9:01 AM, Sean McBride wrote: Let's say I have an Rectangle object. It has properties: colour, width, height. Imagine some controller observing all these properties, perhaps to trigger a redraw. If I do: [rect setColour:...]; [rect setWidth:...]; [rect setHeight:...]; This is short and readable. But observers will be notified after each setter. This could be a problem if intermediate states are not self- consistent and could also lead to unnecessary redrawing. In the general case, I might not even know who is observing. I guess it's safer to create a setColour:width:height: method in my NSManagedObject subclass that does: [self willAccessValueForKey:@colour]; [self willAccessValueForKey:@width]; [self setPrimitiveColour:...]; [self setPrimitiveWidth:...]; [self didAccessValueForKey:@width]; [self didAccessValueForKey:@colour]; Is this what I should be doing? I can see it getting ugly with more than 3 or so properties... ___ 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: Core Data KVO with To-Many Relationships
Since my previous post, I have been able to get the functionality I was hoping for with the following code in my Department subclass. I would greatly appreciate some feedback as to whether this is an appropriate way to implement the functionality or if there is a more efficient or cleaner way. KVO doesn't have an easy way to observe a collection's contents, so the NSNotification approach is your best bet. - (void)awakeFromFetch { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(managedObjectContextDidChange:) name: NSManagedObjectContextObjectsDidChangeNotification object:[self managedObjectContext]]; } - (void)awakeFromInsert { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(managedObjectContextDidChange:) name: NSManagedObjectContextObjectsDidChangeNotification object:[self managedObjectContext]]; } Most people use a 3rd object to do this instead of having the individual managed objects. You can have an innocent bystander observe the NSManagedObjectContextObjectsDidChangeNotification, see if any interesting objects have changed, and then ping them to recompute whatever you need. Much easier to manage registering and unregistering observers. - (void)managedObjectContextDidChange:(NSNotification *)notification { // Get a set containing ALL objects which have been changed NSSet *insertedObjects = [[notification userInfo] objectForKey:NSInsertedObjectsKey]; NSSet *updatedObjects = [[notification userInfo] objectForKey:NSUpdatedObjectsKey]; NSSet *deletedObjects = [[notification userInfo] objectForKey:NSDeletedObjectsKey]; //this method of gathering changed objects is because the final set was always null if the first set was null NSSet *changedObjects; if([insertedObjects count] 0){ changedObjects = [insertedObjects setByAddingObjectsFromSet:updatedObjects]; changedObjects = [changedObjects setByAddingObjectsFromSet:deletedObjects]; }else{ if([updatedObjects count] 0){ changedObjects = [updatedObjects setByAddingObjectsFromSet:deletedObjects]; }else{ changedObjects = [NSSet setWithSet:deletedObjects]; } } if([changedObjects intersectsSet:[self employees]]){ //if an employee in this department changed, indicate that the totalSalary attribute should be refreshed [self willChangeValueForKey:@totalSalary]; [self didChangeValueForKey:@totalSalary]; } } That's the basic idea, but it's easier and faster to do that once, in one master observer, than in each managed object. - Ben ___ 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
Core Data KVO with To-Many Relationships
Hi all. I am working on a Core Data application which contains an entity that needs to be notified of changes in entities that it has a relationship to. Let's talk about this in terms of Apple's example with Departments and Employees. As described here (http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/KeyValueObserving/Concepts/DependentKeys.html) they talk about the example where each Department has a totalSalary attribute and each Employee has a salary attribute. In regards to Core Data, the documentation linked above says this: If you're using Core Data, you can register the parent with the application's notification center as an observer of its managed object context. The parent should respond to relevant change notifications posted by the children in a manner similar to that for key-value observing. I assume this means that something similar to the code posted previously in the article should be done. I understand the statement conceptually, but do not know how to go about implementing it. Here is my start in the Department entity. - (void) awakeFromInsert{ [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(methodToCallOnNotification:) name:??? object:managedObjectContext]; } If this is the correct start, what should happen in methodToCallOnNotification? Do I need to remove each Department entity from being an observer when it is deleted? What else do I need to be sure to do upon Department or Employee creation or deletion? Thank you, John ___ 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
KVC, KVO and dot notation. Was: whether to use core data...
On 3 Oct, 2009, at 23:51, Klaus Backert wrote: On 3 Oct 2009, at 22:06, Colin Howarth wrote: If you use dot notation and properties, you are using the -value and -setValue: accessor methods, which is KVC compliant and means that KVO bits will get notified, no? No. From the documentation The Objective-C 2.0 Programming Language: -- You can think of a property declaration as being equivalent to declaring two accessor methods. Thus @property float value; is equivalent to: - (float)value; - (void)setValue:(float)newValue; A property declaration, however, provides additional information about how the accessor methods are implemented -- Accessing using dot notation myObject.value = x; x = myObject.value; is equivalent to accessing using conventional notation [myObject setValue: x]; x = [myObject value]; This all may be something which is KVC compliant -- or it may not be --, as you can see in the Key-Value Coding Programming Guide, chapter Ensuring KVC Compliance. OK, since this is perhaps a relevant example of what I was talking about, let's compare my off the cuff sentence with the Apple Docs: If you use dot notation and properties, you are using the -value and -setValue: accessor methods, which is KVC compliant and means that KVO bits will get notified, no? Ensuring KVC Compliance In order for a class to be considered KVC compliant for a specific property, it must implement the methods required for valueForKey: and setValue:forKey: to work for that property. Attribute and To-One Relationship Compliance For properties that are an attribute or a to-one relationship, this requires that: • Your class implements a method named -key, -isKey, or has an instance variable key or_key. • If the property is mutable, then it should also implement -setKey:. • Your implementation of the -setKey: method should not perform validation. • Your class should implement -validateKey:error: if validation is appropriate for the key. I have an instance variable named key. The methods -key and - setKey: have been synthesized. Validation is inappropriate Indexed To-Many Relationship Compliance For indexed to-many relationships, KVC compliance requires that your class: • Implements method named -key that returns an array. • Or has an array instance variable named key or _key. • Or implements the method -countOfKey and one or both of - objectInKeyAtIndex: or -keyAtIndexes:. • Optionally, you can also implement -getKey:range: to improve performance. I have an array instance variable named key. Performance is not an issue. For a indexed ordered to-many relationship, KVC compliance requires that your class also: • Implement one or both of the methods -insertObject:inKeyAtIndex: or -insertKey:atIndexes:. • Implement one or both of the methods -removeObjectFromKeyAtIndex: or -removeKeyAtIndexes:. • Optionally, you can also implement - replaceObjectInKeyAtIndex:withObject: or - replaceKeyAtIndexes:withKey: to improve performance. Oooh, tut, tut. That should probably read For a MUTABLE indexed ordered to-many relationship, or, at least, For AN indexed ... Unordered To-Many Relationship Compliance For unordered to-many relationships, KVC compliance requires that your class: • Implements method named -key that returns a set. • Or has an set instance variable named key or _key. • Or implements the methods -countOfKey, -enumeratorOfKey, and - memberOfKey:. Ah. Little typo: Or has A set. I don't have any set instance variables, but if I did, they would be named key. For a mutable unordered to-many relationship, KVC compliance requires that your class also: • Implement one or both of the methods -addKeyObject: or -addKey:. • Implement one or both of the methods -removeKeyObject: or - removeKey:. • Optionally, you can also implement -intersectKey: and -setKey: to improve performance. I don't have a mutable unordered to-many relationship aka as a set So, on the assumption that I have the relevant instance variables, which I do, my statement is basically correct. Except that it doesn't cover instance variables that are mutable unordered or indexed and/or ordered to-many relationships - but then it (my statement) is a little shorter, isn't it? --colin ___ 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: KVO can be unsafe in -init?
Am 09.09.2009 um 11:02 schrieb John Chang: No, it's a singleton. Basically it's a manager object that wants to continually monitor something else for changes. Also, - addObserver is the last line of code in -init, before the return. This article may be of interest to you: http://zathras.de/blog-defensive-coding-in-objective-c.htm Cheers, -- Uli Kusterer The Witnesses of TeachText are everywhere... http://www.zathras.de ___ 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: KVO can be unsafe in -init?
On 13 sep 2009, at 05.33, Jerry Krinock wrote: I'd be interested to know how John is going to fix this problem. I myself have used the performSelector:withObject:afterDelay:0.0 solution in situations like this I think the problem really only happens with the NSKeyValueObservingOptionInitial option, which causes KVO to make a bunch of calls to user code (with potentially lots of side effects) directly inside -addObserver:etc:etc:. So the afterDelay: idea wouldn't really help, since in both cases -addObserver: is going to be catching and rethrowing exceptions. (One of our guys noticed that the crash report had objc_exception_rethrow, instead of objc_exception_throw, which I never noticed until he pointed it out.) The solution was to find and fix the root cause of the exception, but hunting down the source of the exception is the hard part. The above knowledge, however, should help in the future. We were absolutely down the wrong path in suspecting self and -init. /John ___ 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: KVO can be unsafe in -init?
On 2009 Sep 11, at 05:55, John Chang wrote: Just to update you guys. We managed to reproduce the problem in- house and catch it in the debugger. I'd be interested to know how John is going to fix this problem. I myself have used the performSelector:withObject:afterDelay:0.0 solution in situations like this, usually with good results, but it always feels like a kludge, and I worry -- what if someday I also accidentally delay the code that's supposed to run first, to solve a different problem. So I've just moved the problem from crashNow to crashAfterDelay:. Sometimes I feel better if I make the delay .01 or so. The ideal solution is to look around for another method that's somehow guaranteed to run later. That's ideal, but you can't always find one. ___ 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: KVO can be unsafe in -init?
Just to update you guys. We managed to reproduce the problem in-house and catch it in the debugger. The backtrace looks the same as the one in the auto-generated crash reports. (gdb) bt #0 0x02546004 in ___TERMINATING_DUE_TO_UNCAUGHT_EXCEPTION___ () #1 0x98c81f49 in objc_exception_throw () #2 0x00a258de in -[NSObject(NSKeyValueObserverRegistration) addObserver:forKeyPath:options:context:] () The ah-ha is that KVO is catching and re-throwing exceptions in -addObserver:.. If one sets a breakpoint in the code that gets called indirectly, you'll get something much more interesting and sensible: (gdb) bt #0 -[LocalizedIndexedCollation _sectionTitleWithCollationString:] #1 0x000d3d86 in -[LocalizedIndexedCollation sectionForObject:collationStringSelector:] #2 0x000d4335 in -[LocalizedIndexedSectionedList initWithObjects:key:] #3 0x000d59fb in -[SectionedTableViewController setContent:] #4 0x000cc347 in -[FooTableViewController reloadData] #5 0x000ccb2e in -[FooTableViewController setContactGroup:] #6 0x000cb07c in -[FooGroupsTableViewController observeValueForKeyPath:ofObject:change:context:] #7 0x00a76c1e in NSKVONotify () #8 0x00a12e2a in -[NSObject(NSKeyValueObserverNotification) didChangeValueForKey:] () #9 0x00a34a47 in _NSSetUsingKeyValueSetter () #10 0x00a344c5 in -[NSObject(NSKeyValueCoding) setValue:forKey:] () #11 0x0008367b in -[BlahManager(NSKeyValueObserving) observeValueForKeyPath:ofObject:change:context:] #12 0x00a76c1e in NSKVONotify () #13 0x00a2702b in -[NSObject(NSKeyValueObserverRegistration) _addObserver:forProperty:options:context:] () #14 0x00a25872 in -[NSObject(NSKeyValueObserverRegistration) addObserver:forKeyPath:options:context:] () * yes, LocalizedIndexedCollation was my attempt to rewrite UILocalizedIndexedCollation for OS 2.x compatibility You just have to have a good intuition where to look in your own code, I guess, since the crash logs and the debugger won't help much in this case. The best clue comes from the exception itself, but unfortunately that's only in the console log, not the crash reports -- at least not until iPhone OS starts including Application Specific Information like Snow Leopard does. Cheers, /John ___ 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: KVO can be unsafe in -init?
On 08/09/2009, at 12:36 AM, John Chang wrote: Hi all, Question: is it unsafe for some reason to be adding yourself as a KVO observer during -init? We have a singleton with an -init that looks something like this: - (id)init { if ((self = [super init])) { _foo = [[NSMutableDictionary alloc] init]; _bar = [[NSMutableDictionary alloc] init]; [[XYZManager sharedManager] addObserver:self forKeyPath:@allObjects options:NSKeyValueObservingOptionInitial context:NULL]; As a general rule, in ObjC, C++, and Java it's a very bad idea to expose partially constructed objects to third parties, especially via global registries like KVO. In addition to the obvious problems, multi-threading and error handling are especially pernicious. The multi-threading issue is pretty self explanatory. The moment your uninitialized object is registered in KVO, others can invoke methods on it before you and your subclasses are done setting initial state. The error handling issue involves what happens when an initializer needs to error out. In Cocoa, it should return nil, and if necessary, deallocate its previous self (to prevent +alloc from being unbalanced, and hence leak). But this now means that third parties can reach a deallocated object via these registrations. It will complicate how carefully you'll need to write your -dealloc method. If the KVO registration is the last thing that happens, then it'll work, but of course, subclassing will break your assumptions. This falls under the hack category, and is not a pattern you want to replicate widely. - Ben ___ 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: KVO can be unsafe in -init?
On 9 sep 2009, at 04.51, Graham Cox wrote: Because you're trying to use a nil key with a dictionary. Why not set a breakpoint on objc_exception_throw and see where that is being attempted? Because it's happening for some users and not in-house :) On 9 sep 2009, at 05.02, Ken Ferry wrote: Is your -observeValueForKeyPath: safe to be called with a partially set up object? I don't think we're getting that far. (See below) Do you have any subclasses of your object? If so, - observeValueForKeyPath: is getting called on them before they've done their work in init. No, it's a singleton. Basically it's a manager object that wants to continually monitor something else for changes. Also, -addObserver is the last line of code in -init, before the return. On 9 sep 2009, at 05.03, Roland King wrote: One thing to note, you're using a context of NULL, which I used to do all the time until I got badly bitten. What would you recommend using as the context? I'm used to checking object/keyPath, though I noticed as you pointed out that the Xcode template does it with context. On 9 sep 2009, at 05.09, Stephen J. Butler wrote: Why do you think registering the observer is causing this exception? There's nothing KVO related in this message. Sorry, I was thinking of including the backtrace and I guess I didn't. In -init, -addObserver: is only called once, so we're pretty certain about the exact line of code that is being indicated here, unless the stack is lying. Thread 0 Crashed: 0 libSystem.B.dylib 0x31dd594c __kill + 8 1 libSystem.B.dylib 0x31dd593a kill + 4 2 libSystem.B.dylib 0x31dd592e raise + 10 3 libSystem.B.dylib 0x31deccf8 abort + 36 4 libstdc++.6.dylib 0x374ef840 __gnu_cxx::__verbose_terminate_handler() + 588 5 libobjc.A.dylib 0x300166b8 _objc_terminate + 160 6 libstdc++.6.dylib 0x374ecf34 __cxxabiv1::__terminate (void (*)()) + 76 7 libstdc++.6.dylib 0x374ecfac std::terminate() + 16 8 libstdc++.6.dylib 0x374ed060 __cxa_rethrow + 108 9 libobjc.A.dylib 0x30016554 objc_exception_rethrow + 4 10 Foundation 0x305049f6 -[NSObject (NSKeyValueObserverRegistration) addObserver:forKeyPath:options:context:] + 342 11 FooApp -[XYZManager init] (in FooApp) + 548 0x1000 + 375876 12 FooApp +[XYZManager sharedManager] (in FooApp) + 124 0x1000 + 379580 Sun Sep 6 13:41:26 unknown FooApp[1609] Error: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** - [NSCFDictionary setObject:forKey:]: attempt to insert nil key' - (id)init { if ((self = [super init])) { _foo = [[NSMutableDictionary alloc] init]; _bar = [[NSMutableDictionary alloc] init]; [[XYZManager sharedManager] addObserver:self forKeyPath:@allObjects options:NSKeyValueObservingOptionInitial context:NULL]; } return self; } /// What I'm hearing from the various responses is that as a rule, it's not safe to expose self at all during initialization, which makes sense, though in this case, we're stumped as to why it blows up, since by the time we call -addObserver:, self is already valid. In the interim, we're just going to catch that exception. But it's worrisome that we don't understand the root cause. We're thinking of refactoring this class in the future anyway, so this problem could magically go away. Maybe we can just chalk it up to KVO voodoo. Thanks for the responses, /John ___ 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: KVO can be unsafe in -init?
On 9 sep 2009, at 11.21, Mike Abdullah wrote: Well I would question why you're calling +[XYZManager sharedManager] from within -[XYZManager init] like that. What if you change your init routine to: Oops, sorry. It's actually two different classes which I renamed incorrectly for the purposes of this discussion. -[HighLevelObjectDatabase init] wants to listen to [LowLevelObjectManager sharedManager] and observer any changes there. /John ___ 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: KVO can be unsafe in -init?
On 9 Sep 2009, at 10:31, John Chang wrote: On 9 sep 2009, at 11.21, Mike Abdullah wrote: Well I would question why you're calling +[XYZManager sharedManager] from within -[XYZManager init] like that. What if you change your init routine to: Oops, sorry. It's actually two different classes which I renamed incorrectly for the purposes of this discussion. -[HighLevelObjectDatabase init] wants to listen to [LowLevelObjectManager sharedManager] and observer any changes there. I suspected it might be something like that :) In which case, in your stack track, the two items at the bottom are both LowLevelObjectManager? If so, I think you're looking for your bug in the wrong place. It's happening in -[LowLevelObjectManager init], not -[HighLevelObjectDatabase init]. Mike. ___ 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: KVO can be unsafe in -init?
On 09-Sep-2009, at 5:02 PM, John Chang wrote: On 9 sep 2009, at 05.03, Roland King wrote: One thing to note, you're using a context of NULL, which I used to do all the time until I got badly bitten. What would you recommend using as the context? I'm used to checking object/keyPath, though I noticed as you pointed out that the Xcode template does it with context. You have to do both, check the context first, then check the the object/path and if the context is not yours, send it to the superclass. In so much code it doesn't matter, you get used to NULL and then you get a system-generated class which has its own KVO setup, or you subclass something you wrote last year and something which relies on KVO stops working and you've often torn half your code apart before you find it. What do I use. Normally a class static, provided that's granular enough, always has been for me thus far. Either just make some static thing like a character array and take the address of it or, as I've been doing recently, use the address of the class object which I grab in a +initialize() method (taking care again to check I'm not being called for a subclass) and stuff into a static I kept for the purpose. ___ 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: KVO can be unsafe in -init?
What do I use. Normally a class static, provided that's granular enough, always has been for me thus far. Either just make some static thing like a character array and take the address of it or, as I've been doing recently, use the address of the class object which I grab in a +initialize() method (taking care again to check I'm not being called for a subclass) and stuff into a static I kept for the purpose. Personally, for my KVO contexts, I use: static void *const MyClass_KVOContext = (void *)MyClass_KVOContext; I've never seen anyone else use it, but I find it to be the cleanest solution - although it certainly looks strange at first glance. :) ___ 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: KVO can be unsafe in -init?
On 9 Sep 2009, at 11:21, Dave Keck wrote: static void *const MyClass_KVOContext = (void *)MyClass_KVOContext; That certainly is unusual, I use the following macro: #define NSSTRING_CONTEXT(var) static NSString *var = @#var then use the address of the identifier passed as var. This has the benefit of allowing you to print the dereferenced context pointer during debugging. Keith ___ 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: KVO can be unsafe in -init?
We have a singleton with an -init that looks something like this: - (id)init { if ((self = [super init])) { _foo = [[NSMutableDictionary alloc] init]; _bar = [[NSMutableDictionary alloc] init]; [[XYZManager sharedManager] addObserver:self forKeyPath:@allObjects options:NSKeyValueObservingOptionInitial context:NULL]; } return self; } What about writing a method, -finishSetup, and invoke it with a delay like below? I use this pattern a lot with loading views. It seems like it would work so that you add observation when your object is ready. Marc [self performSelectorOnMainThread:@selector(finishSetup) withObject:nil waitUntilDone:NO]; - (void)finishSetup; { [[XYZManager sharedManager] addObserver:self forKeyPath:@allObjects options:NSKeyValueObservingOptionInitial context:NULL]; } ___ 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: KVO can be unsafe in -init?
What about writing a method, -finishSetup, and invoke it with a delay like below? I use this pattern a lot with loading views. It seems like it would work so that you add observation when your object is ready. Marc [self performSelectorOnMainThread:@selector(finishSetup) withObject:nil waitUntilDone:NO]; - (void)finishSetup; { [[XYZManager sharedManager] addObserver:self forKeyPath:@allObjects options:NSKeyValueObservingOptionInitial context:NULL]; } I can see why you'd suggest this and it may well work but .. I have to say .. it's a little ugh. If that sorts out the problem it would mean that even if you are on the very last line of your init method, before you return self, with no subclasses or other issues, your object is still not 'whole' enough to receive messages, messages in this case which are defined on your base class, NSObject, whos init method was finished long ago. I would like to think that isn't the case, certainly no documentation I've ever read has indicated that's the case. Definitely you have to be very thoughtful about what you put in an initializer which references self, and where you put it, more-so if you have subclasses, but my feeling is you should be able to add an observer on another class and get a callback and that callback should work if you've set up the rest of your object beforehand correctly, or at least the bits of it that callback needs. ___ 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: KVO on Distributed Objects with exception handling.
I've just tested it on Snow Leopard (10a380), and it works as expected. Do you happen to remember the technical reasons why KVO on DOs would fail? Ed On Mon, Sep 7, 2009 at 11:55 PM, Scott Anguishsc...@cocoadoc.com wrote: In spite of the fact that it might be working, it isn't supported. When I talked to engineering about this, this is what I was told. He was a bit shocked it worked at all, and it isn't tested as part of releases. On Sep 7, 2009, at 3:02 PM, Edward Chan wrote: Hello, I'm using KVO on a Distributed Object, and I am binding my UI controls based on the observer. For example: MonkeyViewController.isEatingABanana - Binded to a UI checkbox. MonkeyViewController.m: @propery (readwrite, assign) BOOL isEatingABanana; -(id)init { ... [MonkeyBrainDOObject addObserver:self forKeyPath:@banana options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) context:NULL]; ... } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([keyPath isEqualToString:@banana]) { [self willChangeValueForKey:@isEatingABanana]; isEatingABanana = [change objectForKey:NSKeyValueChangeNewKey] boolValue]; [self didChangeValueForKey:@isEatingABanana]; } } - (void)setIsEatingABanana:(BOOL)flag { [MonkeyBrainDOObject setBanana:flag]; isEatingABanana = flag; } This indeed works, and we save some hassles of sending NSNotifications and such. So, what I'm wondering is if the following code is sufficient enough for the IPC exception handling? Instead of having to manually write @try/@catch wherever I doing some IPC, I create a wrapper object around the DO to handle the exceptions. This wrapper class is simply an NSObject, and will call the methods methodSignatureForSelector, and forwardInvocation when I try to use MonkeyBrainDOObject methods (since the wrapper does not understand them). I can then insert a @try/@catch when I forward the invokations to the actual DO object. MonkeyBrainWrapper.m : NSObject - (NSMethodSignature *)methodSignatureForSelector:(SEL)selector { return [MonkeyBrainDOObject methodSignatureForSelector:selector]; // maybe I can use extra code to make sure MonkeyBrainDOObject responds to the selector. } - (void)forwardInvocation:(NSInvocation *)invocation { �...@try { [invocation invokeWithTarget:MonkeyBrainDOObject]; } @catch (NSException *e) { // Oh no! some went wrong with the IPC. But it's ok, I caught you.. :P } } So, instead of calling directly on the MonkeyBrainDOObject in my MonkeyViewController, I would now call my MonkeyBrainWrapper object, which has explicit exception handling rather than the one handle by the NSApplication. Should that be enough for exception handling on both ends of the IPC? Or do I need some explicit exception handling on the other end? It seems when I tested it out, my other end never threw anything when the connection broke. Also, is there maybe a better approach to all of this? My old code had a bunch of NSNotifications being sent/received whenever something needed updating on the UI, and I found this approach to be a lot cleaner. Edward ___ 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/scott%40cocoadoc.com This email sent to sc...@cocoadoc.com ___ 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: KVO on Distributed Objects with exception handling.
On Sep 8, 2009, at 10:38 AM, Edward Chan wrote: I've just tested it on Snow Leopard (10a380), and it works as expected. Perhaps. But as I said, unsupported, untested internally, and could break at any time. Do you happen to remember the technical reasons why KVO on DOs would fail? None given, other than the above. Ed On Mon, Sep 7, 2009 at 11:55 PM, Scott Anguishsc...@cocoadoc.com wrote: In spite of the fact that it might be working, it isn't supported. When I talked to engineering about this, this is what I was told. He was a bit shocked it worked at all, and it isn't tested as part of releases. On Sep 7, 2009, at 3:02 PM, Edward Chan wrote: Hello, I'm using KVO on a Distributed Object, and I am binding my UI controls based on the observer. For example: MonkeyViewController.isEatingABanana - Binded to a UI checkbox. MonkeyViewController.m: @propery (readwrite, assign) BOOL isEatingABanana; -(id)init { ... [MonkeyBrainDOObject addObserver:self forKeyPath:@banana options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) context:NULL]; ... } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([keyPath isEqualToString:@banana]) { [self willChangeValueForKey:@isEatingABanana]; isEatingABanana = [change objectForKey:NSKeyValueChangeNewKey] boolValue]; [self didChangeValueForKey:@isEatingABanana]; } } - (void)setIsEatingABanana:(BOOL)flag { [MonkeyBrainDOObject setBanana:flag]; isEatingABanana = flag; } This indeed works, and we save some hassles of sending NSNotifications and such. So, what I'm wondering is if the following code is sufficient enough for the IPC exception handling? Instead of having to manually write @try/@catch wherever I doing some IPC, I create a wrapper object around the DO to handle the exceptions. This wrapper class is simply an NSObject, and will call the methods methodSignatureForSelector, and forwardInvocation when I try to use MonkeyBrainDOObject methods (since the wrapper does not understand them). I can then insert a @try/@catch when I forward the invokations to the actual DO object. MonkeyBrainWrapper.m : NSObject - (NSMethodSignature *)methodSignatureForSelector:(SEL)selector { return [MonkeyBrainDOObject methodSignatureForSelector:selector]; // maybe I can use extra code to make sure MonkeyBrainDOObject responds to the selector. } - (void)forwardInvocation:(NSInvocation *)invocation { @try { [invocation invokeWithTarget:MonkeyBrainDOObject]; } @catch (NSException *e) { // Oh no! some went wrong with the IPC. But it's ok, I caught you.. :P } } So, instead of calling directly on the MonkeyBrainDOObject in my MonkeyViewController, I would now call my MonkeyBrainWrapper object, which has explicit exception handling rather than the one handle by the NSApplication. Should that be enough for exception handling on both ends of the IPC? Or do I need some explicit exception handling on the other end? It seems when I tested it out, my other end never threw anything when the connection broke. Also, is there maybe a better approach to all of this? My old code had a bunch of NSNotifications being sent/received whenever something needed updating on the UI, and I found this approach to be a lot cleaner. Edward ___ 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/scott %40cocoadoc.com This email sent to sc...@cocoadoc.com ___ 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
KVO can be unsafe in -init?
Hi all, Question: is it unsafe for some reason to be adding yourself as a KVO observer during -init? We have a singleton with an -init that looks something like this: - (id)init { if ((self = [super init])) { _foo = [[NSMutableDictionary alloc] init]; _bar = [[NSMutableDictionary alloc] init]; [[XYZManager sharedManager] addObserver:self forKeyPath:@allObjects options:NSKeyValueObservingOptionInitial context:NULL]; } return self; } This code is running on iPhone OS. On some devices (we haven't been to narrow this down), the last line of code is throwing an exception: Sun Sep 6 13:41:26 unknown MyApp[1609] Error: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSCFDictionary setObject:forKey:]: attempt to insert nil key' We know that [XYZManager sharedManager] can't be nil, since otherwise -addObserver: would not be getting called, and the first line if ((self = [super init])) ensures that self can't be nil. We're pretty sure that [XYZManager sharedManager].allObjects is not nil, but even if it were nil, that shouldn't cause an exception. -allObjects is a synthesized getter with no dependent keys. No other threads are involved here. So we're stumped as to why KVO is throwing an exception. The only theory is that the NSKeyValueObservingOptionInitial option is causing KVO to do something with self immediately, but self isn't fully set up yet. Though it's unclear why in this particular usage that would be unsafe, or why it would make any difference. Can anyone provide any insight? Thanks, /John Stockholm, Sweden ___ 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: KVO on Distributed Objects with exception handling.
On Sep 7, 2009, at 21:45 , Edward Chan wrote: Great... How long ago did you ask the Apple engineers? I haven't tried this piece of code with Snow Leopard actually... This was back in February, I was probably testing on Leopard. The difference between what you and I tried was that I used - bind:toObject:withKeyPath:options: instead of - addObserver:forKeyPath:options:. Did they explain why they didn't want to support it? No, but then the discussion was over Twitter DMs, with all the terseness that entails :-). I do remember eventually sending some sample code to someone in Apple who I seem to recall is on this list, hopefully he is and will be able to explain engineering's reservations more completely. Cheers, Graham. ___ 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: KVO on Distributed Objects with exception handling.
On Sep 7, 2009, at 20:02 , Edward Chan wrote: Hello, I'm using KVO on a Distributed Object, and I am binding my UI controls based on the observer. Hi, not much of constructive help from me I'm afraid, just a warning. I also did the same thing once, and the reaction from Apple engineers went through denial, shock and fear, but never got as far as acceptance. In fact I was told that combining KVO with DO is not supported and if it does work now, don't expect it to work in the future. Cheers, Graham. ___ 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: KVO can be unsafe in -init?
John Chang wrote: Hi all, Question: is it unsafe for some reason to be adding yourself as a KVO observer during -init? We have a singleton with an -init that looks something like this: - (id)init { if ((self = [super init])) { _foo = [[NSMutableDictionary alloc] init]; _bar = [[NSMutableDictionary alloc] init]; [[XYZManager sharedManager] addObserver:self forKeyPath:@allObjects options:NSKeyValueObservingOptionInitial context:NULL]; } return self; } This code is running on iPhone OS. On some devices (we haven't been to narrow this down), the last line of code is throwing an exception: Sun Sep 6 13:41:26 unknown MyApp[1609] Error: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSCFDictionary setObject:forKey:]: attempt to insert nil key' We know that [XYZManager sharedManager] can't be nil, since otherwise -addObserver: would not be getting called, and the first line if ((self = [super init])) ensures that self can't be nil. We're pretty sure that [XYZManager sharedManager].allObjects is not nil, but even if it were nil, that shouldn't cause an exception. -allObjects is a synthesized getter with no dependent keys. No other threads are involved here. So we're stumped as to why KVO is throwing an exception. The only theory is that the NSKeyValueObservingOptionInitial option is causing KVO to do something with self immediately, but self isn't fully set up yet. Though it's unclear why in this particular usage that would be unsafe, or why it would make any difference. Can anyone provide any insight? I don't see anything wrong with what you're attempting to do, as long as you're a little careful. Your NSKeyValueObservingOptionInitial isn't being magically intercepted, I'm quite sure. However that will cause your KVO handler to be executed immediately to give you the initial value, before the registration method returns, are you fully set-up to receive it at that point, is it really the last line before you return self? What happens if your class has been subclassed and that subclass has its own observeValueForKeyPath:ofObject:change:context: method, I'm not entirely sure which one would be called, but I think it would be your subclasses, and your subclass initializer hasn't yet been called. One thing to note, you're using a context of NULL, which I used to do all the time until I got badly bitten. Don't do that, set a context for your observations and check it, the pattern is in the documentation and XCode will even generate a stub for it. You must check the context, you must call the superclass implementation. That would save you by the way in the case you have been subclassed and the subclass method has been called as the contexts wouldn't match and the subclass would pass the observation back up to you. ___ 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: KVO can be unsafe in -init?
On Mon, Sep 7, 2009 at 9:36 AM, John Changjohn.r.ch...@gmail.com wrote: This code is running on iPhone OS. On some devices (we haven't been to narrow this down), the last line of code is throwing an exception: Sun Sep 6 13:41:26 unknown MyApp[1609] Error: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSCFDictionary setObject:forKey:]: attempt to insert nil key' Why do you think registering the observer is causing this exception? There's nothing KVO related in this message. ___ 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: KVO can be unsafe in -init?
On 08/09/2009, at 12:36 AM, John Chang wrote: Hi all, Question: is it unsafe for some reason to be adding yourself as a KVO observer during -init? We have a singleton with an -init that looks something like this: - (id)init { if ((self = [super init])) { _foo = [[NSMutableDictionary alloc] init]; _bar = [[NSMutableDictionary alloc] init]; [[XYZManager sharedManager] addObserver:self forKeyPath:@allObjects options:NSKeyValueObservingOptionInitial context:NULL]; NSKeyValueObservingInitial will trigger an immediate send of the KVO notification to self. Since you're still inside -init I wouldn't have thought that was generally safe, though it may be in certain cases. Sun Sep 6 13:41:26 unknown MyApp[1609] Error: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSCFDictionary setObject:forKey:]: attempt to insert nil key' So we're stumped as to why KVO is throwing an exception. Because you're trying to use a nil key with a dictionary. Why not set a breakpoint on objc_exception_throw and see where that is being attempted? The only theory is that the NSKeyValueObservingOptionInitial option is causing KVO to do something with self immediately It is. , but self isn't fully set up yet. Though it's unclear why in this particular usage that would be unsafe true, it's unclear. But debugging the exception should show you what's happening. --Graham ___ 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: KVO can be unsafe in -init?
Hi John, Since you're passing NSKeyValueObservingOptionInitial, -observeValueForKeyPath: is going to be invoked on your object immediately, before the method even returns. Is your -observeValueForKeyPath: safe to be called with a partially set up object? Do you have any subclasses of your object? If so, -observeValueForKeyPath: is getting called on them before they've done their work in init. -Ken On Mon, Sep 7, 2009 at 7:36 AM, John Chang john.r.ch...@gmail.com wrote: Hi all, Question: is it unsafe for some reason to be adding yourself as a KVO observer during -init? We have a singleton with an -init that looks something like this: - (id)init { if ((self = [super init])) { _foo = [[NSMutableDictionary alloc] init]; _bar = [[NSMutableDictionary alloc] init]; [[XYZManager sharedManager] addObserver:self forKeyPath:@allObjects options:NSKeyValueObservingOptionInitial context:NULL]; } return self; } This code is running on iPhone OS. On some devices (we haven't been to narrow this down), the last line of code is throwing an exception: Sun Sep 6 13:41:26 unknown MyApp[1609] Error: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSCFDictionary setObject:forKey:]: attempt to insert nil key' We know that [XYZManager sharedManager] can't be nil, since otherwise -addObserver: would not be getting called, and the first line if ((self = [super init])) ensures that self can't be nil. We're pretty sure that [XYZManager sharedManager].allObjects is not nil, but even if it were nil, that shouldn't cause an exception. -allObjects is a synthesized getter with no dependent keys. No other threads are involved here. So we're stumped as to why KVO is throwing an exception. The only theory is that the NSKeyValueObservingOptionInitial option is causing KVO to do something with self immediately, but self isn't fully set up yet. Though it's unclear why in this particular usage that would be unsafe, or why it would make any difference. Can anyone provide any insight? Thanks, /John Stockholm, Sweden ___ 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/kenferry%40gmail.com This email sent to kenfe...@gmail.com ___ 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
KVO on Distributed Objects with exception handling.
Hello, I'm using KVO on a Distributed Object, and I am binding my UI controls based on the observer. For example: MonkeyViewController.isEatingABanana - Binded to a UI checkbox. MonkeyViewController.m: @propery (readwrite, assign) BOOL isEatingABanana; -(id)init { ... [MonkeyBrainDOObject addObserver:self forKeyPath:@banana options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) context:NULL]; ... } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([keyPath isEqualToString:@banana]) { [self willChangeValueForKey:@isEatingABanana]; isEatingABanana = [change objectForKey:NSKeyValueChangeNewKey] boolValue]; [self didChangeValueForKey:@isEatingABanana]; } } - (void)setIsEatingABanana:(BOOL)flag { [MonkeyBrainDOObject setBanana:flag]; isEatingABanana = flag; } This indeed works, and we save some hassles of sending NSNotifications and such. So, what I'm wondering is if the following code is sufficient enough for the IPC exception handling? Instead of having to manually write @try/@catch wherever I doing some IPC, I create a wrapper object around the DO to handle the exceptions. This wrapper class is simply an NSObject, and will call the methods methodSignatureForSelector, and forwardInvocation when I try to use MonkeyBrainDOObject methods (since the wrapper does not understand them). I can then insert a @try/@catch when I forward the invokations to the actual DO object. MonkeyBrainWrapper.m : NSObject - (NSMethodSignature *)methodSignatureForSelector:(SEL)selector { return [MonkeyBrainDOObject methodSignatureForSelector:selector]; // maybe I can use extra code to make sure MonkeyBrainDOObject responds to the selector. } - (void)forwardInvocation:(NSInvocation *)invocation { @try { [invocation invokeWithTarget:MonkeyBrainDOObject]; } @catch (NSException *e) { // Oh no! some went wrong with the IPC. But it's ok, I caught you.. :P } } So, instead of calling directly on the MonkeyBrainDOObject in my MonkeyViewController, I would now call my MonkeyBrainWrapper object, which has explicit exception handling rather than the one handle by the NSApplication. Should that be enough for exception handling on both ends of the IPC? Or do I need some explicit exception handling on the other end? It seems when I tested it out, my other end never threw anything when the connection broke. Also, is there maybe a better approach to all of this? My old code had a bunch of NSNotifications being sent/received whenever something needed updating on the UI, and I found this approach to be a lot cleaner. Edward ___ 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: KVO on Distributed Objects with exception handling.
Great... How long ago did you ask the Apple engineers? I haven't tried this piece of code with Snow Leopard actually... On Mon, Sep 7, 2009 at 3:29 PM, Graham Leel...@thaesofereode.info wrote: On Sep 7, 2009, at 20:02 , Edward Chan wrote: Hello, I'm using KVO on a Distributed Object, and I am binding my UI controls based on the observer. Hi, not much of constructive help from me I'm afraid, just a warning. I also did the same thing once, and the reaction from Apple engineers went through denial, shock and fear, but never got as far as acceptance. In fact I was told that combining KVO with DO is not supported and if it does work now, don't expect it to work in the future. Cheers, Graham. ___ 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: KVO on Distributed Objects with exception handling.
Also, Did they explain why they didn't want to support it? Thanks, Ed On Mon, Sep 7, 2009 at 4:45 PM, Edward Chanedch...@gmail.com wrote: Great... How long ago did you ask the Apple engineers? I haven't tried this piece of code with Snow Leopard actually... On Mon, Sep 7, 2009 at 3:29 PM, Graham Leel...@thaesofereode.info wrote: On Sep 7, 2009, at 20:02 , Edward Chan wrote: Hello, I'm using KVO on a Distributed Object, and I am binding my UI controls based on the observer. Hi, not much of constructive help from me I'm afraid, just a warning. I also did the same thing once, and the reaction from Apple engineers went through denial, shock and fear, but never got as far as acceptance. In fact I was told that combining KVO with DO is not supported and if it does work now, don't expect it to work in the future. Cheers, Graham. ___ 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: KVO on Distributed Objects with exception handling.
In spite of the fact that it might be working, it isn't supported. When I talked to engineering about this, this is what I was told. He was a bit shocked it worked at all, and it isn't tested as part of releases. On Sep 7, 2009, at 3:02 PM, Edward Chan wrote: Hello, I'm using KVO on a Distributed Object, and I am binding my UI controls based on the observer. For example: MonkeyViewController.isEatingABanana - Binded to a UI checkbox. MonkeyViewController.m: @propery (readwrite, assign) BOOL isEatingABanana; -(id)init { ... [MonkeyBrainDOObject addObserver:self forKeyPath:@banana options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) context:NULL]; ... } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([keyPath isEqualToString:@banana]) { [self willChangeValueForKey:@isEatingABanana]; isEatingABanana = [change objectForKey:NSKeyValueChangeNewKey] boolValue]; [self didChangeValueForKey:@isEatingABanana]; } } - (void)setIsEatingABanana:(BOOL)flag { [MonkeyBrainDOObject setBanana:flag]; isEatingABanana = flag; } This indeed works, and we save some hassles of sending NSNotifications and such. So, what I'm wondering is if the following code is sufficient enough for the IPC exception handling? Instead of having to manually write @try/@catch wherever I doing some IPC, I create a wrapper object around the DO to handle the exceptions. This wrapper class is simply an NSObject, and will call the methods methodSignatureForSelector, and forwardInvocation when I try to use MonkeyBrainDOObject methods (since the wrapper does not understand them). I can then insert a @try/@catch when I forward the invokations to the actual DO object. MonkeyBrainWrapper.m : NSObject - (NSMethodSignature *)methodSignatureForSelector:(SEL)selector { return [MonkeyBrainDOObject methodSignatureForSelector:selector]; // maybe I can use extra code to make sure MonkeyBrainDOObject responds to the selector. } - (void)forwardInvocation:(NSInvocation *)invocation { @try { [invocation invokeWithTarget:MonkeyBrainDOObject]; } @catch (NSException *e) { // Oh no! some went wrong with the IPC. But it's ok, I caught you.. :P } } So, instead of calling directly on the MonkeyBrainDOObject in my MonkeyViewController, I would now call my MonkeyBrainWrapper object, which has explicit exception handling rather than the one handle by the NSApplication. Should that be enough for exception handling on both ends of the IPC? Or do I need some explicit exception handling on the other end? It seems when I tested it out, my other end never threw anything when the connection broke. Also, is there maybe a better approach to all of this? My old code had a bunch of NSNotifications being sent/received whenever something needed updating on the UI, and I found this approach to be a lot cleaner. Edward ___ 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/scott%40cocoadoc.com This email sent to sc...@cocoadoc.com ___ 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: KVO on Distributed Objects with exception handling.
On Sep 7, 2009, at 4:45 PM, Edward Chan wrote: Great... How long ago did you ask the Apple engineers? I haven't tried this piece of code with Snow Leopard actually... It still isn't supported in SL. I'd be shocked if it ever is. ___ 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: Changes in KVO behavior on SL?
On Sep 1, 2009, at 6:11 PM, Ken Thomases wrote: On Sep 1, 2009, at 7:14 PM, Kevin Brock wrote: We've got an app that is using keyValueForPath: and observeValueForKeyPath:ofObject:change:context: to keep a status window up-to-date. On 10.5 it works fine. On 10.6 keyValueForPath: is called exactly once per property. When we later create a change dictionary and send observeValueForKeyPath:ofObject:change:context: to the observer for a property, valueForKeyPath: isn't called again. Huh? You have never been supposed to call - observeValueForKeyPath:ofObject:change:context: yourself, nor construct change dictionaries. When a property changes in a way that KVO can't automatically track, you are supposed to call -will/ didChangeValueForKey: (or the corresponding will/didChange... methods for set or array mutation) and KVO will generate the change notification itself. Good to know. I'll give that a try. Lot of legacy code in that part of the app--I doubt that this is the last thing I'll run into. Likewise, there's never been any guarantee that invoking - observeValueForKeyPath:ofObject:change:context: will provoke the receiver to call -valueForKeyPath: on the object whose property has changed. If the observer wants, it can rely totally on the information in the change dictionary. If you were using will/ didChange..., then KVO can be expected to invoke valueForKey: on the object whose property is changing, but that's not what (you say) you're doing. Thanks. That was helpful. On 10.5 the receiver *does* apparently always call valueForKeyPath, at least with the receivers we're talking to. Maybe they weren't checking the dictionary on 10.5, or were calling the fn if the data on the new values wasn't found in the dictionary, but are being stricter on 10.6. Kevin ___ 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: Changes in KVO behavior on SL?
On 2 Sep 2009, at 13:47, Kevin Brock wrote: Likewise, there's never been any guarantee that invoking - observeValueForKeyPath:ofObject:change:context: will provoke the receiver to call -valueForKeyPath: on the object whose property has changed. If the observer wants, it can rely totally on the information in the change dictionary. If you were using will/ didChange..., then KVO can be expected to invoke valueForKey: on the object whose property is changing, but that's not what (you say) you're doing. Thanks. That was helpful. On 10.5 the receiver *does* apparently always call valueForKeyPath, at least with the receivers we're talking to. Maybe they weren't checking the dictionary on 10.5, or were calling the fn if the data on the new values wasn't found in the dictionary, but are being stricter on 10.6. Ken didn't contradict the behaviour you have observed. But you are [were] relying on a mechanism that is undocumented and quite possibly accidental on the part of Apple's engineers, and so could have changed at any time, or might have been erratic/fragile even on 10.5. In other words, it is merely fortunate that your app ever worked on 10.5, and not by design ;-) The documented pattern that Ken described should work on both 10.5 and 10.6, and will always work... until deprecated anyway! ___ 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
Changes in KVO behavior on SL?
We've got an app that is using keyValueForPath: and observeValueForKeyPath:ofObject:change:context: to keep a status window up-to-date. On 10.5 it works fine. On 10.6 keyValueForPath: is called exactly once per property. When we later create a change dictionary and send observeValueForKeyPath:ofObject:change:context: to the observer for a property, valueForKeyPath: isn't called again. Is there a known change in 10.6 to how these functions are supposed to work? It's really odd, because all of our low-level code, including some KEXTs, works fine in 32 bit SL, but this one piece doesn't... Kevin ___ 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: Changes in KVO behavior on SL?
On Tue, Sep 1, 2009 at 5:14 PM, Kevin Brockap...@kevin.com wrote: We've got an app that is using keyValueForPath: and observeValueForKeyPath:ofObject:change:context: to keep a status window up-to-date. It's valueForKeyPath:. On 10.5 it works fine. On 10.6 keyValueForPath: is called exactly once per property. When we later create a change dictionary and send observeValueForKeyPath:ofObject:change:context: to the observer for a property, valueForKeyPath: isn't called again. You need to post your code. Is there a known change in 10.6 to how these functions are supposed to work? It's really odd, because all of our low-level code, including some KEXTs, works fine in 32 bit SL, but this one piece doesn't... There are changes -- read the release notes. None of them should introduce the behavior you're seeing. --Kyle Sluder ___ 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
KVO: when to stop observing?
Hi, In my program, I rely heavily on key-value observing (KVO), which I find really useful. However, I haven't found a good way to know when I should stop observing, i.e. call removeObserver:forKeyPath:. Until now, my solution has been to start observing in the designated initialiser, and to stop observing in the dealloc method. This solution kind of works, but has several drawbacks: 1. It doesn't work with GC, first because GC doesn't call dealloc and second because the simple fact that my object is registered as an observer probably prevents it from being collected in the first place (I haven't checked, but that's what I gather from messages found in this list's archive). Even if it didn't, stopping the observation in finalize wouldn't be ideal, as object would keep getting notifications for some time after becoming unreachable. 2. I have to be careful when I use this technique on CoreAnimation layers, since CA uses the initWithLayer: method to create presentation layers during animations. If initWithLayer: doesn't invoke the designated initialiser, then the presentation layer doesn't observe anything, and the program crashes when its dealloc method tries to call removeObserver:forKeyPath:. The solution I have found for this is to keep track of whether a layer is a presentation layer or not, and only call removeObserver:forKeyPath: for non- presentation layers. That's ugly. Overall, I have something that works but isn't elegant at all. I'm therefore looking for better solutions, and would be interested to know what people have come up with. It seems to me that the only clean solution would be to detect when an object is dead and then call a method to make it stop all its observations, but this is equivalent to solving the memory management problem by hand, which is painful. Thanks, Michel. ___ 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: KVO: when to stop observing?
If you're targeting 10.6 only, this is taken care of you automatically according to the Foundation release notes. Any KVO observers will be automagically removed as observers by the runtime, and thus you won't have to do it at all. The release notes hint that the appropriate solution for 10.5 is to perform this inside your -finalize method. (Obviously this whole reply pertains only to garbage-collected environments). -- Steven Degutis http://www.thoughtfultree.com/ http://www.degutis.org/ On Sun, Aug 30, 2009 at 1:59 AM, Michel Schinz michel.schinz.li...@gmail.com wrote: Hi, In my program, I rely heavily on key-value observing (KVO), which I find really useful. However, I haven't found a good way to know when I should stop observing, i.e. call removeObserver:forKeyPath:. Until now, my solution has been to start observing in the designated initialiser, and to stop observing in the dealloc method. This solution kind of works, but has several drawbacks: 1. It doesn't work with GC, first because GC doesn't call dealloc and second because the simple fact that my object is registered as an observer probably prevents it from being collected in the first place (I haven't checked, but that's what I gather from messages found in this list's archive). Even if it didn't, stopping the observation in finalize wouldn't be ideal, as object would keep getting notifications for some time after becoming unreachable. 2. I have to be careful when I use this technique on CoreAnimation layers, since CA uses the initWithLayer: method to create presentation layers during animations. If initWithLayer: doesn't invoke the designated initialiser, then the presentation layer doesn't observe anything, and the program crashes when its dealloc method tries to call removeObserver:forKeyPath:. The solution I have found for this is to keep track of whether a layer is a presentation layer or not, and only call removeObserver:forKeyPath: for non-presentation layers. That's ugly. Overall, I have something that works but isn't elegant at all. I'm therefore looking for better solutions, and would be interested to know what people have come up with. It seems to me that the only clean solution would be to detect when an object is dead and then call a method to make it stop all its observations, but this is equivalent to solving the memory management problem by hand, which is painful. Thanks, Michel. ___ 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/steven.degutis%40gmail.com This email sent to steven.degu...@gmail.com ___ 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