ゴール
ブロックをプラグインして特定のイベントを受け取るために使用できるさまざまなプロパティを持つクラスがあります。
@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)init
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
ブロックを模倣して、受信した呼び出しを配列に転送する必要があります。
ここで説明されている手法を使用できますか?
すべての呼び出しをインターセプトし、配列要素ごとにコピーして、新しい呼び出しターゲットを割り当てているのでしょうか?