实验了几种做法,其中二和三可以实现, 但仅粗略验证, 可能有未知的问题.
-
NSNotificationCenter加一个category, 添加一个associatedObject为一个数组.
-
替换NSNotificationCenter的 addObserver... 方法, 新方法中用一个 Wrapper对象来封装传进来的Observer.
-
想通过真正的observer被释放时触发wrapper的 realObserver setter方法, 从而移除通知.
//Wrapper.h @interface Wrapper : NSObject @property (nonatomic, weak) id realObserver; @property (nonatomic, assign) id assignObserver; @end @implemantation Wrapper - (void)setRealObserver:(id)observer { if(nil == observer ){ if(self.assignObserver){ [[NSNotificationCenter defaultCenter] removerObserver:self.assignObserver]; self.assignObserver = nil; } } _realObserver = observer; } @end
// NSNotificationCenter(Hooked).m - (void)hooed_addObserver:(id)observer ... { Wrapper *wrapper = [[Wrapper alloc] init]; wrapper.realObserver = observer; wrapper.assignObserver = observer; [self.wrapperArray addObject:wrapper];// wrapper array 是NSNotificationCenter defaultCenter的一个associated object . [self origin_addObserver:observer ...]; }
####二、@卡迩 提供思路:给每一个Observer添加一个Associated object 如AssO
, AssO
一个weak属性指向Observer,试图通过Observer释放时会先释放AssO
, 从而在AssO
的dealloc中通过weak移除Observer.
~~
结果: 实验代码表明, 一个对象的Dealloc方法是先于Associated Objectd的Dealloc方法调用的, 所以在Associated Object的dealloc中去释放通知已经晚了.
~~