Is there any way to delegate to two objects at a time in Objective-C? I know that delegation pattern implies one response at a time and for multiple listeners and broadcasting there is notification center but notification does not return any value.
If I have a heavily network-based iOS project and need to delegate to multiple listeners and required to return values from them, in this scenario what approach should be the best?
The multicast delegate contains a list of the assigned delegates. When the multicast delegate is called, it invokes the delegates in the list, in order. Only delegates of the same type can be combined. The - operator can be used to remove a component delegate from a multicast delegate.
Save. Multicast Delegate is a generic wrapper around yet another delegate protocol, that means it create one-to-many delegate relationships. This allows providing an object with an array of delegates.
Delegates allow methods to be passed as parameters. Delegates can be used to define callback methods. Delegates can be chained together; for example, multiple methods can be called on a single event. Methods don't have to match the delegate type exactly.
In every class the delegate is one, so one delegate is informed about the event. But nothing forbids you to declare a class with a set of delegates.
Or use Observation instead. A class may be observed by multiple classes.
Example
As requested from the OP, since also some code would be useful, here is a way of doing it:
@interface YourClass() @property (nonatomic, strong, readwrite) NSPointerArray* delegates; // The user of the class shouldn't even know about this array // It has to be initialized with the NSPointerFunctionsWeakMemory option so it doesn't retain objects @end @implementation YourClass @synthesize delegates; ... // other methods, make sure to initialize the delegates set with alloc-initWithOptions:NSPointerFunctionsWeakMemory - (void) addDelegate: (id<YourDelegateProtocol>) delegate { [delegates addPointer: delegate]; } - (void) removeDelegate: (id<YourDelegateProtocol>) delegate { // Remove the pointer from the array for(int i=0; i<delegates.count; i++) { if(delegate == [delegates pointerAtIndex: i]) { [delegates removePointerAtIndex: i]; break; } } // You may want to modify this code to throw an exception if no object is found inside the delegates array } @end
This is a very simple version, you can do it in another way. I don't suggest to make public the delegates set, you never know how it could be used, and you can get an inconsistent state, specially with multithreading. Also, when you add/remove a delegate you may need to run additional code, so that's why making the delegates set private.
You may also a lot of other methods like delegatesCount
for example.
PS: The code has been edited to be a NSPointerArray instead of a NSMutableSet, because as stated in the comments a delegate should be held with a weak pointer to avoid retain cycles.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With