Multicast Delegate Pattern
delegateは処理の一部を委譲するときに使うものです。
この通知先を複数にする方法を紹介します。
使用例
MultiDelegateProxy *delegateProxy = [[MultiDelegateProxy alloc] initWithTarget:self, nil];
[delegateProxy addTarget:xxx];
[delegateProxy addTarget:zzz];
self.scrollView.delegate = (id)delegateProxy;
実装例
MultiDelegateProxy.h
#import <Foundation/Foundation.h>
@interface MultiDelegateProxy : NSProxy
- (instancetype)initWithTarget:(NSObject *)targets, ... NS_REQUIRES_NIL_TERMINATION;
- (void)addTarget:(NSObject *)target;
- (void)removeTarget:(NSObject *)target;
@end
MultiDelegateProxy.m
#import "MultiDelegateProxy.h"
@interface MultiDelegateProxy ()
@property (strong, nonatomic) NSMutableArray* targets;
@end
@implementation MultiDelegateProxy
- (instancetype)initWithTarget:(NSObject *)targets, ... {
_targets = @[].mutableCopy;
va_list arguments;
va_start(arguments, targets);
NSObject *value = targets;
while (value) {
[_targets addObject:value];
value = va_arg(arguments, typeof(NSObject*));
}
va_end(arguments);
return _targets.count ? self : nil;
}
- (void)forwardInvocation:(NSInvocation *)invocation {
for(NSObject *target in _targets.copy) {
if ([target respondsToSelector:invocation.selector]) {
[invocation invokeWithTarget:target];
}
}
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
for(NSObject *target in _targets.copy) {
if ([target respondsToSelector:sel]) {
return [target methodSignatureForSelector:sel];
}
}
return nil;
}
- (BOOL)respondsToSelector:(SEL)aSelector {
if ([super respondsToSelector:aSelector]) {
return YES;
}
for(NSObject *target in _targets.copy) {
if ([target respondsToSelector:aSelector]) {
return YES;
}
}
return NO;
}
- (BOOL)conformsToProtocol:(Protocol *)aProtocol {
for(NSObject *target in _targets.copy) {
if ([target conformsToProtocol:aProtocol]) {
return YES;
}
}
return NO;
}
- (void)addTarget:(NSObject *)target {
if (target && ![_targets containsObject:target]) {
[_targets addObject:target];
}
}
- (void)removeTarget:(NSObject *)target {
if (target && [_targets containsObject:target]) {
[_targets removeObject:target];
}
}
@end
参考リンク
Article
http://blog.fenrir-inc.com/jp/2013/11/nsproxy.html
http://blog.scottlogic.com/2012/11/19/a-multicast-delegate-pattern-for-ios-controls.html
http://www.gregread.com/2016/02/23/multicast-delegates-in-swift/
OSS
https://github.com/tumtumtum/SwiftMulticastDelegate
https://github.com/jonasman/MulticastDelegate