How to allow one thread to change the property of an array, and another thread iterates on a copy of the array

I would like to implement the observer pattern in Objective-C, where the observer implements an interface similar to SKPaymentTransactionObserver , and the observed class simply extends my base. My observable class looks something like below. Notice that I make copies of observers before listing to avoid an exception.

I tried adding NSLock around adding watchers and notifying watchers, but I ran into a dead end.

What would be the proper way to handle concurrency when observers are added when notifications are sent?

@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]; } } 
+4
source share
2 answers

What is the problem with the current code? Is this a dead end? Could you think of a specific deadlock scenario? Did you try to only synchronize a copy of the array? Like this:

 - (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]; } } 
+2
source

Could you please choose a simpler notification method?

+1
source

Source: https://habr.com/ru/post/1304664/


All Articles