2

多くの場合、他の多くのブロックを実行するためだけに機能する「ラッパー」ブロックを作成していることに気付くことがよくあります。通常は同じ型シグネチャを使用します。

同じ型シグネチャを持つ 2 つのブロックがあるとします。

MyBlockT block1 = ^(NSString *string, id object) {
    //1 does some work
};

MyBlockT block2 = ^(NSString *string, id object) {
    //2 does some other work
};

Combine()2ブロックかかる魔法の関数を実装する方法はありますか:

MyBlockT combinedBlock = Combine(block1, block2); //hypothetical function

そして、次のことと同等です:

MyBlockT combinedBlock = ^(NSString *string, id object) {
    block1(string, object);
    block2(string, object);
};

これは を返すブロックでのみ意味があることは知っていますvoidが、私が興味を持っているのはそれだけです。

このCombine関数は 2 つのブロックを取り込むだけで済みます。さらにブロックがある場合は、それらを連鎖させることができます。これを実装する方法、またはそれが可能であるかどうかについて、私は機知に富んでいます。

PSソリューションにCマクロが含まれていてもかまいません

編集

結果のブロックをメソッドの引数として使用できるようにしたいと思います。

[UIView animateWithDuration:1 animations:someCombinedBlock];
4

5 に答える 5

4

これはあなたが探しているものですか?

MyBlockT CombineBlocks(MyBlockT block1, MyBlockT block2)
{
    return [^(NSString *string, id object) {
        block1(string, object);
        block2(string, object);
    } copy];
}

この関数は、指定された 2 つのブロックを順番に呼び出す新しいブロックを作成します。

于 2013-07-14T10:58:11.100 に答える
1

以下は、可変引数の楽しい乱用です。

id combine(id block, ...)
{
        NSMutableArray *blocks = [NSMutableArray array];
        //[blocks addObject:block];
        va_list objlist;
        va_start(objlist, block);
        //while((obj = va_arg(ap, id))) { // }
        for(id obj = block; obj; obj = va_arg(objlist, id)) {
                [blocks addObject:[obj copy]];
        }
        va_end(objlist);
        void (^wrapper)(id,...) = ^(id arg, ...) {
                NSMutableArray *args = [NSMutableArray array];
                va_list arglist;
                va_start(arglist, arg);
                for(id x = arg; x; x = va_arg(arglist, id)) {
                        [args addObject:x];
                }
                va_end(arglist);

                for(void (^blk)() in blocks) {
                        blk(args);
                }
        };
        return [wrapper copy];
}

int main() {
        NSString *fmt = @"-%d-\n%@\n---";
        void (^foo)() = combine(^(NSArray *a){ NSLog(fmt, 1, a); },
                                ^(NSArray *a){ NSLog(fmt, 2, a); }, nil);
        foo(@"first", @"second", nil);
        return 0;
}

引数の NSArray を受け入れるように各ブロックを定義する必要があります。またcombine、結果のブロック呼び出しの両方に、少なくとも 1 つの引数があり、 で終わる必要がありますnil

メソッドのシグネチャが事前にわかっている場合は、ラッパー ブロックを適切に変更することで、NSArray とブロック引数の制限を回避できます。

于 2013-07-14T19:34:32.813 に答える
0

2 つ以上のアニメーションを同時に実行する必要がある場合は、 RZViewActionsで十分です。そのコードはほとんど呼び出しのように見えanimateWithDuration:...ますが、追加機能があります。

任意のブロックを同時に実行する必要がある場合は、 ReactiveCocoaのようなものが必要です。しかし、PromiseKitをお勧めします(単純に簡単だからです)。

于 2015-08-03T07:42:08.963 に答える
0

あなたはマクロを気にしないので

#define combinedBlock(string, object)      \
         block1((string), (object) )       \            
         block2((string), (object) )
于 2013-07-14T10:50:12.363 に答える