我想在Objective-C中实现一个观察者模式,其中观察者实现类似于SKPaymentTransactionObserver的接口,而observable类只是扩展我的基地可观察。我可观察的类看起来像下面的内容。请注意,在枚举之前我要复制观察者,以避免投掷exception。如何让一个线程改变数组属性,而另一个线程在数组副本上迭代
我试着添加一个NSLock添加观察者并通知观察者,但我遇到了一个死锁。
当正在发送通知时添加观察者时处理并发性的正确方法是什么?
@implementation Observable
-(void)notifyObservers:(SEL)selector {
@synchronized(self) {
NSSet* observer_copy = [observers copy];
for (id observer in observer_copy) {
if([observer respondsToSelector: selector]) {
[observer performSelector: selector];
}
}
[observer_copy release];
}
}
-(void)notifyObservers:(SEL)selector withObject:(id)arg1 withObject:(id)arg2 {
@synchronized(self) {
NSSet* observer_copy = [observers copy];
for (id observer in observer_copy) {
if([observer respondsToSelector: selector]) {
[observer performSelector: selector withObject: arg1 withObject: arg2];
}
}
[observer_copy release];
}
}
-(void)addObserver:(id)observer {
@synchronized(self) {
[observers addObject: observer];
}
}
-(void)removeObserver:(id)observer {
@synchronized(self) {
[observers removeObject: observer];
}
}
当前的代码实际上工作正常,但我不得不在迭代之前复制数组,以避免在修改数组时引发异常。我在通知周围添加了共享的NSLock,并添加了导致死锁的观察者方法。我可以发布死锁的代码。 – lolsborn 2010-03-21 06:45:16
啊哈!我认为副本很好。除非证明它是一个瓶颈,否则我会忘记它。我曾经在即时游戏的主循环中复制和分配数组。 – zoul 2010-03-21 07:00:25