仿照https://github.com/X-Team-X/SimpleKVO寫的掂铐,添加KVO和Notification觀察者非常容易品擎,自動移除observer埋合。不需要手動在dealloc中添加如下代碼:
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillEnterForegroundNotification object:nil];
[self.tableView removeObserver:self forKeyPath:NSStringFromSelector(@selector(contentOffset))];
}
用block的方式傳回回調(diào),而且也不用擔(dān)心沒有移除observer導(dǎo)致的crash了萄传,用法如下:
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView addObserverForKeyPath:NSStringFromSelector(@selector(contentOffset)) block:^(__weak id obj, id oldValue, id newValue) {
NSLog(@"old value:%@ new value:%@", NSStringFromCGPoint([oldValue CGPointValue]), NSStringFromCGPoint([newValue CGPointValue]));
}];
[self addNotificationForName:UIApplicationWillEnterForegroundNotification block:^(NSNotification *notification) {
NSLog(@"will enter forground");
}];
}
自動移除observer的原理很簡單甚颂,因為我們一般在dealloc方法里面做remove observer的操作。那么就hook dealloc方法就好了:
// 替換dealloc方法秀菱,自動注銷observer
+ (void)load
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Method originalDealloc = class_getInstanceMethod(self, NSSelectorFromString(@"dealloc"));
Method newDealloc = class_getInstanceMethod(self, @selector(autoRemoveObserverDealloc));
method_exchangeImplementations(originalDealloc, newDealloc);
});
}
- (void)autoRemoveObserverDealloc
{
if (objc_getAssociatedObject(self, &KTKvoObserversKey) || objc_getAssociatedObject(self, &KTNotificationObserversKey)) {
[self removeAllObserverBlocks];
[self removeAllNotificationBlocks];
}
// 下面這句相當(dāng)于直接調(diào)用dealloc
[self autoRemoveObserverDealloc];
}
完整項目在這里SimpleKVONotification