Вопрос

I have read the apple document about KVO, and it said:

Note: The key-value observing addObserver:forKeyPath:options:context: method does not maintain strong references to the observing object, the observed objects, or the context. You should ensure that you maintain strong references to the observing, and observed, objects, and the context as necessary.

The observer object not have a strong references to the observered object.

Does this man I can not call removeObserver:forKeyPath: in the dealloc method? Can it remove the observer automatically?

Это было полезно?

Решение

You must call -removeObserver:forKeyPath: manaully. iOS will not do it automatically.

Apple said does not maintain strong references to the observing object. I think it means, if you want to removeObserver for a temp var out off the temp var's scope, you should make the temp var as ivar, so you maintain the ivar's strong references.

If you do not call -removeObserver:forKeyPath:. You will make : 1) Something leak

such as you code like this :

[self addObserver:a forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];

if you do not call -removeObserver:forKeyPath:. It will console that :

An instance 0x756a1d0 of class MyClass 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 0x7574f60] ( [NSKeyValueObservance 0x7574f20: Observer: 0x7568280, Key path: pageCount, Options: [New: YES, Old: NO, Prior: NO] Context: 0x0, Property: 0x7574fa0] )

When you debug it, you will find : The self and the a are not leaking. The leaking thing is the NSKeyValueObservationInfo object

If you do not call -removeObserver:forKeyPath:. You will make : 2) Intermediate class never destroy && Infinity notification

As the Apple document about KVO says:

When an observer is registered for an attribute of an object the isa pointer of the observed object is modified, pointing to an intermediate class rather than at the true class.

When you removeObserver, if no observer is registered, the intermediate class will destroy. And If you not call removeObserver, the intermediate class will never destroy and when you change the property, the setter method of intermediate class will continue to send notifications.

Другие советы

removeObserver:forKeyPath: has nothing to do with memory management or maintaining references. It just tells the runtime that your object no longer needs to be informed of changes to the object at that keyPath.

No, you must call -removerObserver:forKeyPath: when it is no longer needed, else the KVO system will have some dangling pointers that may leak or become attached to another object that doesn't expect it.

no, you have to call it.

not strong is NOT always weak

but in this case it means unsafe_unretained.

If you don't remove the observer you get an error message: "the object XY was deallocated while there was still a observer"

AND it might crash

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top