• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Cannot remove an observer ... because it is not registered as an observer.
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Cannot remove an observer ... because it is not registered as an observer.


  • Subject: Re: Cannot remove an observer ... because it is not registered as an observer.
  • From: Steve Steinitz <email@hidden>
  • Date: Tue, 6 May 2008 23:27:29 +1000

Summary:

    KVO compliance discussion
    Detailed problem description
    Request (to Jens) for clarification
    What I've tried
    A failed workaround
    A crappy, unsound workaround


Hi Jens, Jack and List Participants,

Thanks, Jens, for your reply.

On 4/5/08, Jens Alfke wrote:

Cannot remove an observer <NSTableBinder 0x158a70> for the key path "name" from <Alternative 0x15abd0> because it is not registered as an observer.

"It" refers to the observer. -removeObserver:forKeyPath: raises this exception if told to remove an object that isn't currently registered as an observer. So what's happening is that a table view is trying to unregister as an observer from one of your objects that it unfortunately didn't previouly register as an observer for.

The usual cause of this is that you have a property that isn't KVO-compliant.

All my properties have a setters and getters and have the appropriate calls to


    will|did Access|Change ValueForKey

before/after any change.  Is there more that I need to do?

For what its worth, let me explain exactly what is causing the problem.

Firstly, the 'Contribution' Entity is more-or-less a many to many join table (but with a 'degree' attribute) between 'Alternatives' and 'Values'.

I have a simple but unusual arrangement of what is displayed in the 'degree' column of my 'Alternatives' tableView. Depending on the selection in a 'Values' tableView, I show the 'degree' attribute of a certain set of 'Contribution' objects (basically, the related 'Contributions' of the selected 'Value' -- there will be one for each 'Alternative'). i.e. Every time the user changes the 'Values' table selection, the degree column of the Alternatives' tableView changes to show the 'degree' attributes of a new set of 'Contributions'. That change causes the "cannot remove an observer" exceptions.

Simple idea, hard to explain. It could more easily have been a very wide tableView with a column for each 'Contribution', the column label being the name of the relevant 'Value'. The current technique avoids at least three undesirable aspects:

    variable number of table columns,
    truncated column labels,
    horizontal scrolling.

Those undesirables will be even more so when the app is also a web app.

Something accesses your 'foo' property and registers as an observer of
that property, and also as an observer of the object that's the
property's current value;

Jens, can you please elaborate on that distinction? I was not aware that something could be an observer of an object.


you change the value of 'foo' without letting anyone know; the
observer then later decides to stop observing, gets your 'foo'
property, and removes itself as an observer of that object. But it's
no longer the same object that it registered as an observer for...

OK. I made a guess that the culprit was ether the 'Alternative' tableView or the 'Alternative' ArrayController. So, in my WindowController's awakeFromNib, I tried adding them as observers for the 'degree' property (the one the exception complains about) for all 'Contribution' objects, like so:


NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity: [NSEntityDescription entityForName: @"Contribution"
inManagedObjectContext: [self managedObjectContext]]];


NSArray *contributions = [[self managedObjectContext] executeFetchRequest: fetchRequest error: &error];
[fetchRequest release];


for (Contribution *aContribution in contributions)
{
[aContribution addObserver: alternativeTableView
forKeyPath: @"degree"
options: (NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld)
context: NULL];
[aContribution addObserver: alternatives
forKeyPath: @"degree"
options: (NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld)
context: NULL];
}


It didn't help. Either the addObserver is insufficient or I still don't know what the "it" is in the error message. (Or, I've created over-observance as mentioned by Jack.)

In desperation, I added try-catch around each step of the code that throws exceptions and discovered that these two lines throw :

[selectedAlternative setContributionForSelectedDecisionValue: nil]; // KVO dummy setter
[alternativeArrayController rearrangeObjects];


but this line doesn't throw

    [alternativeTableView   reloadData];

In the short-term, I've caught the two exceptions -- that has allowed the application to more-or-less work. But it doesn't bode well for the future. For one thing, any subsequent [alternativeArrayController rearrangeObjects] will fail.

I know of at least two other people struggling with this problem and have seen others encounter it in the past. It would be great to have an answer here in the list archives.

Thanks,

Steve

_______________________________________________

Cocoa-dev mailing list (email@hidden)

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

Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Follow-Ups:
    • Re: Cannot remove an observer ... because it is not registered as an observer.
      • From: "Hamish Allan" <email@hidden>
  • Prev by Date: Re: Threading - How its done?
  • Next by Date: Resetting IKImageEditPanel's Effects Selection
  • Previous by thread: Re: Blob Detection with Core Image
  • Next by thread: Re: Cannot remove an observer ... because it is not registered as an observer.
  • Index(es):
    • Date
    • Thread