- 使用way1 【正常用法】
#import "NSObject+FBKVOController.h"
[self.KVOController observe:self.label keyPath:@"text" options:NSKeyValueObservingOptionNew block:^(id _Nullable observer, id _Nonnull object, NSDictionary * _Nonnull change) {
//weakSelf
weakSelf.count ++;
if (weakSelf.count == 1) {
NSLog(@"weakSelf:%@",weakSelf);
NSLog(@"label:%@",weakSelf.label);
}
}];
FBKVOController 方便之处在于,不需要在dealloc里调用
-(void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath
- 使用way2【当self observe self
时】
[self.KVOControllerNonRetaining observe:self keyPath:@"numStr" options:NSKeyValueObservingOptionNew block:^(id _Nullable observer, id _Nonnull object, NSDictionary * _Nonnull change) {
//weakSelf
NSLog(@"%@",weakSelf.numStr);
}];
- 这时,需要使用KVOControllerNonRetaining,否则出现retainCycle
- 这时,还需要手动调用
removeObserver:
... orself.KVOControllerNonRetaining unobserve:
...
具体原因可以看源码~
/**
@abstract Lazy-loaded FBKVOController for use with any object
@return FBKVOController associated with this object, creating one if necessary
@discussion This makes it convenient to simply create and forget a FBKVOController.
Use this version when a strong reference between controller and observed object would create a retain cycle.
When not retaining observed objects, special care must be taken to remove observation info prior to deallocation of the observed object.
*/
@property (nonatomic, strong) FBKVOController *KVOControllerNonRetaining;
另外,这种self observe self
实在没有必要用kvo,直接在setter方法中处理即可嘛。
举例
在cell中使用时, 若直接在dealloc中移除kvo
- (void)dealloc
{
[self.KVOControllerNonRetaining unobserve:self];
}
发现友盟上 部分系统和机型会崩溃
崩溃日志
An instance 0x155536e00 of class ***Cell was deallocated while key value observers were still registered with it. Current observation info: ( Context: 0x15685bff0, Property: 0x1568b3720>
原因: 使用KVOControllerNonRetaining
注意
special care must be taken to remove observation info prior to deallocation of the observed object
要在dealloc
方法走之前 remove observation
,didMoveToSuperview
方法正好合适
解决方式:
- (void)didMoveToSuperview
{
[super didMoveToSuperview];
if (self.superview) {
[self.KVOControllerNonRetaining observe:self keyPath: ...]
}else {
[self.KVOControllerNonRetaining unobserve:self];
}
}
手绘引用图(恐怕只有自己才能看懂)