Multicast delegates - multiple classes receiving n

2020-07-15 15:11发布

问题:

I understand that UI controls such as UITextField notify of client interactions / events via their delegate, which is defined as a class that supports the required protocol.

I have often found myself wanting to receive notifications of UI event in more than one class, so would want to support multicasting. For example, specifying more than one delegate for a UI control. I am pretty sure that there is no iOS framework feature that supports this. I was wondering if anyone had come up with a decent solution to this problem?

回答1:

There is a cocoa feature that lets you build multicast delegates with relative ease - it's the Message Forwarding system built into the framework.

Make a class that overrides forwardInvocation:, and return an instance of your object instead of a delegate. This is what is sometimes called a "Trampoline object". The logic inside your forwardInvocation: implementation can now decide which "real" objects should receive the message, and forward the invocation to one or more of them.

As an update to this accepted answer, I created my own multicasting delegate implementation here:

http://www.scottlogic.co.uk/blog/colin/2012/11/a-multicast-delegate-pattern-for-ios-controls/



回答2:

You could implement your UI control in your class, and then your class will receive notification from this UI, you can send message to another class (using the same delegate technic - implement delegate property in first class, and then in second class implement delegate method from 1-st class). For example, for UITextField method -textFieldDidEndEditing:

In first class -

1) implement protocol:

@protocol TextControllerDelegate <NSObject>

@optional // Delegate protocols
- (void)textFieldDidEndEditing:(UITextField *)textField;

@end

2) @property (nonatomic, unsafe_unretained, readwrite) id <TextControllerDelegate> delegate;

3)in method - (void)textFieldDidEndEditing:(UITextField *)textField inside the class, call [delegate textFieldDidEndEditing:textField]

In second class:

1) implement object of first class, set delegate to self (to second class).

2) implement method - (void)textFieldDidEndEditing:(UITextField *)textField



回答3:

One technique to support multicasting is to give your delegating class the following methods:

@interface Delegator : NSObject - (void)addDelegate:(id<MyProtocol>)delegate; - (void)removeDelegate:(id<MyProtocol>)delegate; @end

And store the reference to the delegates in an NSHashTable.

See the implementation here: http://arielelkin.github.io/articles/objective-c-multicast-delegate/