我想知道同样的事情,但我找不到它的记录。这就是我认为正在发生的事情。
removeObserver:
不是你想要的线程安全的。
考虑以下情况。在线程 A 上执行代码时释放对观察者的最后一个引用。线程 A 将调用观察者的dealloc
方法。同时,被观察对象[NSNotificcationCenter postNotificationName:object:]
从线程 B 执行 a。这导致了不可避免的竞争条件。也就是说,当您的对象在其方法中时,通知将在飞行中。dealloc
- (void)init {
...
[[NSNotificcationCenter defaultCenter] addObserver:self
selector:@selector(callback:)
name:@"whatever"
object:nil];
...
}
- (void)dealloc {
// If the observed object posts the notification on thread B while
// thread A is here, there's a race! At best, thread B will be
// in callback: while thread A is here in dealloc. That's probably
// not what you expect. The worst case is that thread B won't make
// make it to callback: until after thread A completes the dealloc
// and the memory has been freed. Likely crash!
[[NSNotificationCenter defaultCenter] removeObserver:self];
// If the observed object does the post when thread A is here,
// you'll be fine since the observation has been removed.
}
对于只观察其他主线程对象的主线程对象来说,这不是问题,因为根据定义,您无法进入我描述的线程 A 和 B 场景。
对于多线程情况,保证您避免该问题的唯一方法是确保观察在观察者的引用计数达到 0之前停止。如果其他人负责观察者的生命周期(即您有任何类型的term
或close
方法) , 这很简单。如果没有,我不知道解决方案。