2010-03-20 71 views
4

我想在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]; 
    } 
} 

回答

2

當前代碼有什麼問題?這是一個僵局嗎?你能想到具體的死鎖場景嗎?您是否嘗試僅同步陣列副本?像這樣:

- (void) notify { 
    @synchronized(self) { 
     NSSet *observersCopy = [observers copy]; 
    } 
    for (id observer in observersCopy) 
     [observer doSomething]; 
    [observersCopy release]; 
} 

- (void) addObserver: (id) observer { 
    @synchronized(self) { 
     [observers addObject:observer]; 
    } 
} 
+0

當前的代碼實際上工作正常,但我不得不在迭代之前複製數組,以避免在修改數組時引發異常。我在通知周圍添加了共享的NSLock,並添加了導致死鎖的觀察者方法。我可以發佈死鎖的代碼。 – lolsborn 2010-03-21 06:45:16

+1

啊哈!我認爲副本很好。除非證明它是一個瓶頸,否則我會忘記它。我曾經在即時遊戲的主循環中複製和分配數組。 – zoul 2010-03-21 07:00:25

1

你不能選擇的notifications更簡單的方法?

+0

這裏有一些討論:http://www.cocoadev.com/index.pl?NotificationsAcrossThreads關於如何在多線程應用中使用NSNotification實例。一個條目使用pthreads而不是'NSLock',但原則應該大致相同。 – 2010-03-20 23:11:16

+0

通知中心似乎不適合我想要做的事情。許多通知回調採用各種參數,使用類似於SKPaymentTransactionObserver的觀察者界面更加直觀。 – lolsborn 2010-03-21 02:59:05

相關問題