3

SOLVED - it turns out that passing nil to removeObserver:forKeyPath: fails, but ONLY in manual memory management. It works fine in garbage collected mode. The Apple documentation does NOT say it requires a non-nil value so I'm assuming it's a bug.

I have an object that adds itself as an observer of itself, via [self addObserver:self forKeyPath: etc. In my -dealloc method (note that I am using retain counts and NOT the garbage collector) I call [self removeObserver:self forKeyPath:nil]; which should work. However, I get the following error:

Cannot remove an observer <Snapshot 0x10047a6d0> for the key path "(null)" from <Snapshot 0x10047a6d0> because it is not registered as an observer.

Now, if I remove that line so it doesn't remove itself, I get this message:

An instance 0x100193580 of class Snapshot 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 0x1001be2f0> (
<NSKeyValueObservance 0x1001a0a00: Observer: 0x100193580, Key path: fileURL, Options: <New: YES, Old: NO, Prior: NO> Context: 0x0, Property: 0x1001a02f0>
)

So… the object is observing itself… and yet it isn't? :D Notice in the second message, the observer has the same address as the instance being deallocated, so it is indeed the same object.

The line [self removeObserver:self forKeyPath:nil]; worked before when it was garbage-collected when called from -finalize but not now from -dealloc in manually managed code.

Any thoughts?

jstm88
  • 3,335
  • 4
  • 38
  • 55
  • I guess that by "garbage collected mode" you actually mean "Automatic Reference Counting mode" (ARC). Please, correct this in your question, as garbage-collection and ARC are completely different things. – Ricardo Sanchez-Saez Jan 10 '13 at 15:22
  • Downvoting because of wrong statements regarding `nil` value for keyPath when removing observers. – Nikolai Ruhe Nov 11 '13 at 09:59

1 Answers1

9

Should the key path really be nil? from Apple documentation:

http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Protocols/NSKeyValueObserving_Protocol/Reference/Reference.html

The key path, relative to the receiver, of the property to observe. This value must not be nil.

Mattias Wadman
  • 11,172
  • 2
  • 42
  • 57
  • The documentation requires non-nil values for addObserver… messages, but not for for removing observers - passing nil there removes all observations for that object, instead of having to remove each explicitly (there could be multiple ones). – jstm88 Oct 06 '11 at 21:42
  • However, despite the fact that the documentation does not state the necessity of non-nil values for removeObserver:forKeyPath:, it does indeed work with the key passed instead of nil. With garbage collection, nil works, but in manual management, nil fails. I think we've discovered a bug… :) – jstm88 Oct 06 '11 at 21:50
  • Ah ok. Didn't know that `nil` key path to `removeObserver:forKeyPath:` removed all key paths for the observer. Is that documented somewhere? can't find it. – Mattias Wadman Oct 06 '11 at 21:55
  • It's not documented but I've seen it done, and I can confirm it works… but only in garbage collected mode. Maybe that's why it's undocumented. ;) – jstm88 Oct 06 '11 at 21:59
  • Just fixed the post as well. I had used the "quote" option to show the error messages but the angle brackets were causing it to think it was HTML. Now you can actually see it, although it's not really necessary now. – jstm88 Oct 06 '11 at 22:02
  • 3
    removeObserver:forKeyPath: is optional under GC since KVO registration is weak. Under manual reference counting, it's unretained. Are you sure that's not whats making this work? Passing nil as the keyPath sounds bogus and it sounds like you're remembering the features of NSNotificationCenter's observer removing methods. – Jon Hess Oct 07 '11 at 05:02
  • I guess that by "garbage collected mode" you guys actually mean "Automatic Reference Counting mode" (ARC). Please, duly note this, as garbage-collection and ARC are completely different ways of memory management. – Ricardo Sanchez-Saez Jan 10 '13 at 15:24
  • 2
    As he mentions [finalize](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/finalize) I think he is referring to garbage collection that is available when building for Mac OS X – Mattias Wadman Jan 10 '13 at 19:46
  • It's not possible to remove observers using nil for the keyPath. @jfm429 just mixed up NSNotificationCenter and KVO here. – Nikolai Ruhe Nov 11 '13 at 10:01