目标
我有一个具有各种属性的类,可用于插入块以接收某些事件。
@interface SomeClass
@property (copy, nonatomic) void (^handler)(int arg1, int arg2);
@end
在客户端代码中,我想动态地向这个属性添加/删除处理程序块,类似于 C# 中的 MulticastDelegate。
self.logger = ^(int arg1, int arg2){
NSLog(@"arg1 = %d, arg2 = %d", arg1, arg2);
};
void (^doSomething)(int, int) = ^(int arg1, int arg2){
if (arg1 == 42) {
// Do something.
}
};
例如,我想插入,但只logger
在某个方法运行时使用。插上电源后,仍应运行。-(id)init
doSomething
doSomething
logger
当前实施
为了维护块,我考虑使用NSMutableArray
存储块的副本并将事件广播到所有已注册的块(观察者模式)。
- (id)初始化
self.handlerBlocks = [NSMutableArray array];
__weak typeof(self) weakSelf = self;
self.object.handler = ^(int x, int y){
typeof(self) strongSelf = weakSelf;
if (!strongSelf) {
return;
}
for (void (^item)(int x, int y) in strongSelf.handlerBlocks) {
item(x, y);
}
};
[self.handlerBlocks addObject:[self.logger copy]];
- (void)someOtherMethod
void (^doSomething)(int, int) = [^(int arg1, int arg2){
if (arg1 == 42) {
// Do something.
}
} copy];
[self.handlerBlocks addObject:doSomething copy];
// Do something.
[self.handlerBlocks removeObject:doSomething];
开放式问题
该方法可以推广到具有任何参数计数/类型的块吗?这样我就可以像这样使用它:
MulticastBlock *b = [[MulticastBlock alloc] init];
self.object.handler = b;
[b addBlock:self.logger];
这里的问题是类型self.object.handler
是void (^)(int, int)
. 因此,MulticastBlock
需要模仿一个块,将它收到的任何调用转发到数组。
可以使用这里描述的技术吗?
也许拦截所有调用,为每个数组元素复制它们并分配新的调用目标?