注意:
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath
options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath
context:(nullable void *)context
API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0));
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;
1,使用kvo监听对象时,在对象销毁的时候,如果没有移除所有的监听者,将导致奔溃
Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: 'An instance 0x60800001dd20 of class Fizz was deallocated
while key value observers were still registered with it.
Current observation info: <NSKeyValueObservationInfo 0x60800003d320> (
<NSKeyValueObservance 0x608000057310: Observer: 0x7fa098f07590, Key path: number,
Options: <New: YES, Old: YES, Prior: NO> Context: 0x0, Property: 0x608000057400>
)'
2,没有注册监听者时,如果进行移除监听者操作,也会奔溃
Terminating app due to uncaught exception 'NSRangeException',
reason: 'Cannot remove an observer <ViewController 0x141e298e0>
for the key path "text" from <UILabel 0x141e29de0> because it is not registered as an observer.'
3,提前释放监听者
在移除监听者之前,如果监听者被释放,当监听到事件的时候,程序奔溃;并且监听者被释放了,我们就无法正确的移除监听者了,被监听的对象释放时也会导致奔溃
4,上下文对象 context
如果传入了上下文对象,移除监听者时也需要传入上下文对象,使用相应的移除方法
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath context:(nullable void *)context
如何传入上下文对象
[self.label addObserver:self forKeyPath:@"text" options:NSKeyValueObservingOptionOld context:(void *)@"dddd"];
获取上下文对象
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
NSLog(@"context = %@", (__bridge NSString *)context);
}