Re: removeObserver:forKeyPath:context: fails; but removeObserver:forKeyPath: works?!

2015-03-12 Thread Quincey Morris
On Mar 12, 2015, at 03:01 , Jonathan Mitchell  wrote:
> 
> But surely this is the whole point of the context - to be able to 
> differentiate between multiple observations to the same object and path.

I think the point is to differentiate between multiple observations to the same 
object and path *from different objects*. I’m not convinced whether multiple 
observations to the same object and path to the same object are intended to be 
allowed or not.

Even if so, but if the observation created by the binding *doesn’t* use the 
context for removal — presumably because that piece of code predates the 
context-based removal API, and hasn’t been changed since — then the possibility 
for confusion still exists.

I found the original thread about the bug I referred to earlier:

http://www.cocoabuilder.com/archive/cocoa/239182-crash-in-kvo-when-using-keypathsforvaluesaffecting-key.html
 


(Nearly 6 years ago, can you believe it?) I don’t know whether it’s the same 
problem, but in both cases the frameworks are internally creating an 
observation that’s the same as a code-created observation (apart from context). 
Apparently the removal code was unable to properly distinguish between the two 
observations, and that’s more or less what Sean reported.

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: removeObserver:forKeyPath:context: fails; but removeObserver:forKeyPath: works?!

2015-03-12 Thread Jonathan Mitchell

> On 11 Mar 2015, at 23:28, Quincey Morris 
>  wrote:
> 
> 
> I don’t have an explanation of exactly why that might fail, but it certainly 
> seems a lot like the conditions for bug I talked about earlier. You have the 
> same object observing the same property of the same target twice.
> 
But surely this is the whole point of the context - to be able to differentiate 
between multiple observations to the same object and path.
When observing complex objects it is useful to be able to do this.
I do it on occasion and it works fine.

Having said that I agree that the OP’s usage within a bind override looks 
convoluted.

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: removeObserver:forKeyPath:context: fails; but removeObserver:forKeyPath: works?!

2015-03-12 Thread Sean McBride
On Wed, 11 Mar 2015 23:28:08 +, Quincey Morris said:

>— I don’t think it’s a very good idea to do this (slightly abbreviated
>from your source):
>
>> - (void)bind:(NSString*)inBindingName toObject:(id)inObservableObject
>withKeyPath:(NSString*)inKeyPath  options:(NSDictionary*)inOptions {
>>  [inObservableObject addObserver:self  forKeyPath:inKeyPath options:0
>context:context];
>>  [super bind:inBindingName toObject:inObservableObject
>withKeyPath:inKeyPath options:inOptions];
>> }
>
>The standard implementation of bindings, which you’re using when you
>invoke super, *also* adds the exact same observation as you just did
>(though with a different or nil context, presumably).
>
>When you invoke super in ‘unbind', I guess it’s using the context-less
>form of removeObserver.

Thanks for your analysis; I concur with it.

Not using bindings isn't an option, at least not in the short/medium term.  The 
app was started back when we had ibplugins and uses bindings heavily.

Regarding your prescriptions, I was going to say 'but I'm doing it just as 
mmalc's old binding examples suggested' but then I went to look up the old 
BindingsJoystick sample code and see that it was updated in 2012, which I never 
noticed.  I swear they changed how they do things.  Now bind: and unbind: only 
call super if the binding name is not the class' own, and now they implement 
infoForbinding:.  My SCM history shows that unconditionally calling super was 
necessary for ibplugins to work properly, which is moot now.

So I guess my solution is to only call super in bind: and unbind: for binding 
names that aren't mine, and to also override infoForBinding: to return info for 
my own bindings, and again only call super for super's bindings.

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: removeObserver:forKeyPath:context: fails; but removeObserver:forKeyPath: works?!

2015-03-11 Thread Quincey Morris
On Mar 11, 2015, at 15:03 , Sean McBride  wrote:

> It's here:

I just spent a few minutes with it. A couple of things:

— I don’t think it’s a very good idea to do this (slightly abbreviated from 
your source):

> - (void)bind:(NSString*)inBindingName toObject:(id)inObservableObject 
> withKeyPath:(NSString*)inKeyPath  options:(NSDictionary*)inOptions {
>   [inObservableObject addObserver:self  forKeyPath:inKeyPath options:0 
> context:context];
>   [super bind:inBindingName toObject:inObservableObject 
> withKeyPath:inKeyPath options:inOptions];
> }

The standard implementation of bindings, which you’re using when you invoke 
super, *also* adds the exact same observation as you just did (though with a 
different or nil context, presumably).

When you invoke super in ‘unbind', I guess it’s using the context-less form of 
removeObserver.

I don’t have an explanation of exactly why that might fail, but it certainly 
seems a lot like the conditions for bug I talked about earlier. You have the 
same object observing the same property of the same target twice.

I would suggest you simply don’t do this to the binding, or better still don’t 
use a binding here at all. But of course my opinion here is basically 
valueless, since I don’t know the design of your app.

— I commented out the super ‘bind’ in the above method to see what would 
happen. After also commenting out the various asserts, I ended up with this log 
output:

> •BIND: ptr: 0x61140bb0, tag: 1, name: "crosshairsTransform", context: 
> 123456
> •BIND: ptr: 0x61140c60, tag: 2, name: "crosshairsTransform", context: 
> 123456
> •BIND: ptr: 0x61140b00, tag: 3, name: "crosshairsTransform", context: 
> 123456
> •OBSERVE: ptr: 0x61140bb0, tag: 1: keyPath: "selection.crosshairs", 
> context: 123456
> •OBSERVE: ptr: 0x61140c60, tag: 2: keyPath: "selection.crosshairs", 
> context: 123456
> •OBSERVE: ptr: 0x61140b00, tag: 3: keyPath: "selection.crosshairs", 
> context: 123456
> •UNBIND: ptr: 0x61140c60, tag: 2, name: "crosshairsTransform", context: 
> 123456, hasInfo: 0
> •UNBIND: ptr: 0x61140b00, tag: 3, name: "crosshairsTransform", context: 
> 123456, hasInfo: 0
> •DEALLOC: ptr: 0x61140b00, tag: 3
> •DEALLOC: ptr: 0x61140c60, tag: 2
> •OBSERVE: ptr: 0x61140bb0, tag: 1: keyPath: "selection.crosshairs", 
> context: 123456

which I think is the behavior you’re looking for. (Of course, the app crashed 
shortly after that, because the object controller didn’t have any content, or 
some such consequence of the missing binding.)

To my mind, that confirms that the multiple-identical-observation scenario is 
the problem.


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: removeObserver:forKeyPath:context: fails; but removeObserver:forKeyPath: works?!

2015-03-11 Thread Sean McBride
On Wed, 11 Mar 2015 20:24:34 +, Quincey Morris said:

>Sure, I’d be interested to see it.

Cool, thanks.  It's here:



To repro:
 - search for all the NSLogs in the project (4 of them) and put breakpoints 
there
 - build & launch
 - you may need to do File > New to get the window to appear
 - the window has 3 custom views. bind is called from windowDidLoad
 - press the top push button (it mutates an NSManageObject)
 - watch the logs, each of the 3 views will observe the change
 - press the bottom push button (it unbinds and removes 2of3 views)
 - watch the logs
 - press the top push button again

Expected:
 - the remaining view should have observed the change

Actual:
 - the remaining view does not even get into observeValueForKeyPath

Notes:
 - if you toggle the #if in the unbind: implementation you can "fix" the bug

Cheers,

-- 

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: removeObserver:forKeyPath:context: fails; but removeObserver:forKeyPath: works?!

2015-03-11 Thread Sean McBride
On Wed, 11 Mar 2015 21:06:46 +, Jonathan Mitchell said:

>I recently refactored my app to use removeObserver:forKeyPath:context:
>rather than removeObserver:forKeyPath and it went without a hitch.

We did the same refactor a couple of years ago, and it went great also.  We 
missed just one or two, and as per Murphy's Law one is being problematic. :)

>are you using for your context pointers? Mine are always non nil
>pointers to a static char.

Likewise.

Cheers,

-- 

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: removeObserver:forKeyPath:context: fails; but removeObserver:forKeyPath: works?!

2015-03-11 Thread Jonathan Mitchell

> On 11 Mar 2015, at 18:31, Sean McBride  wrote:
> 
> On Tue, 10 Mar 2015 18:25:23 +, Quincey Morris said:
> 
>> If something else is using a conflicting ‘removeObserver:forKeyPath:’,
>> it might sorta work if all observers use it (because the total number of
>> removals is equal to the number of observations, even if they remove
>> each others’ observations), but fail if some try use
>> ‘removeObserver:forKeyPath:context:’ on an observation that’s already
>> been removed.
> 
> It must be something like that.  I've gutted my app down to test case size 
> and it still reproduces. :(  If you're curious I can put it online.
I recently refactored my app to use removeObserver:forKeyPath:context: rather 
than removeObserver:forKeyPath and it went without a hitch. What are you using 
for your context pointers? Mine are always non nil pointers to a static char.

> 
>> Also, a long time ago (Leopard-ish), there was a horrible bug where
>> observations of (from?) the same thing could get mixed up so that
>> attempting to remove one would actually remove the other. I doubt this
>> was ever fixed — it was subtle.
> 
> The Foundation Release Notes speak of similar things being fixed... but maybe 
> there is another bug...
> 
> Cheers,
> 
> -- 
> 
> 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:
> https://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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: removeObserver:forKeyPath:context: fails; but removeObserver:forKeyPath: works?!

2015-03-11 Thread Quincey Morris
On Mar 11, 2015, at 11:31 , Sean McBride  wrote:
> 
> If you're curious I can put it online.

Sure, I’d be interested to see it.

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: removeObserver:forKeyPath:context: fails; but removeObserver:forKeyPath: works?!

2015-03-11 Thread Sean McBride
On Tue, 10 Mar 2015 18:25:23 +, Quincey Morris said:

>If something else is using a conflicting ‘removeObserver:forKeyPath:’,
>it might sorta work if all observers use it (because the total number of
>removals is equal to the number of observations, even if they remove
>each others’ observations), but fail if some try use
>‘removeObserver:forKeyPath:context:’ on an observation that’s already
>been removed.

It must be something like that.  I've gutted my app down to test case size and 
it still reproduces. :(  If you're curious I can put it online.

>Also, a long time ago (Leopard-ish), there was a horrible bug where
>observations of (from?) the same thing could get mixed up so that
>attempting to remove one would actually remove the other. I doubt this
>was ever fixed — it was subtle.

The Foundation Release Notes speak of similar things being fixed... but maybe 
there is another bug...

Cheers,

-- 

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: removeObserver:forKeyPath:context: fails; but removeObserver:forKeyPath: works?!

2015-03-10 Thread Quincey Morris
On Mar 10, 2015, at 10:50 , Sean McBride  wrote:
> 
> Can anyone think of a sitation where using removeObserver:forKeyPath: works 
> correctly, then modernizing the code to use 
> removeObserver:forKeyPath:context: breaks things?

If something else is using a conflicting ‘removeObserver:forKeyPath:’, it might 
sorta work if all observers use it (because the total number of removals is 
equal to the number of observations, even if they remove each others’ 
observations), but fail if some try use ‘removeObserver:forKeyPath:context:’ on 
an observation that’s already been removed.

Also, a long time ago (Leopard-ish), there was a horrible bug where 
observations of (from?) the same thing could get mixed up so that attempting to 
remove one would actually remove the other. I doubt this was ever fixed — it 
was subtle.

So, all this, plus the odd backtrace that *might* indicate that the object 
controller is duplicating one of your observations, but without a context, and 
things are falling apart from there.

Unless something easy turns out to have been overlooked, this sounds TSI-worthy.



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: removeObserver:forKeyPath:context: fails; but removeObserver:forKeyPath: works?!

2015-03-10 Thread Keary Suska
On Mar 10, 2015, at 11:50 AM, Sean McBride  wrote:

> Hi all,
> 
> Can anyone think of a sitation where using removeObserver:forKeyPath: works 
> correctly, then modernizing the code to use 
> removeObserver:forKeyPath:context: breaks things?
> 
> Long story: I have a custom NSView subclass that exposes a custom binding.  
> In bind: it does addObserver:forKeyPath:options:context:.  In unbind: it does 
> removeObserver:forKeyPath:.  If I update unbind: to use the 'context' version 
> it breaks.
> 
> Specifically, if I have several of these views onscreen (all bound to the 
> same NSObjectController) then remove all but one of the views from the view 
> hierarchy, the remaining one no longer receives any KVO notifications.  I've 
> put logs everywhere, and subclassed NSObjectController and implemented 
> add&removeObserver methods to log and call super.  All the log output is the 
> same in the working & broken cases except the deliberate difference between 
> using removeObserver: with or without the context.  I am surprised to see 
> this backtrace however:
> 
> -[MyObjectController removeObserver:forKeyPath:]
> -[NSObject(NSKeyValueObserverRegistration) 
> removeObserver:forKeyPath:context:] ()
> -[NSController removeObserver:forKeyPath:context:] ()
> -[MyObjectController removeObserver:forKeyPath:context:]
> -[MyView unbind:]
> ...
> 
> Odd that NSObjectController removeObserver:forKeyPath:context: calls 
> removeObserver:forKeyPath:, no?
> 
> Any clues would help... :)

Have you checked observationInfo at each point to ensure that observation is 
being added/removed exactly as you expect?

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com