2

重複の可能性:
ブロックを配列に格納する

特定の条件に基づいて、特定のイベントが発生した後に特定のコードを実行したいアプリケーションを作成しています。このコードは、このコードを実行する必要があるときにスコープ内にない関数内の変数にアクセスする複数の場所にある可能性があります。これらのステートメントをブロックとして配列内に格納し、イベントが発生したときにそれらを 1 つずつ実行することは可能ですか。はいの場合、以前のスコープの変数にアクセスするにはどうすればよいですか?

これをクロージャーの配列として作りたかったのです。

4

2 に答える 2

2

@foggzilla が言うように、ブロックを NSMutableArray (または同様のもの) に入れる前に、ブロックをコピーする必要があります。

例えば

[myArray addObject:[myBlock copy]];

コピー セレクターは直接 Block_copy 関数にマップされるため、それを使用する必要はありません。ARCを使用している場合、ブロックを解放する必要はありません。

ブロックをコレクションに入れる前に、必ずブロックをコピーする必要があります。

于 2012-11-19T21:28:21.343 に答える
2

Block_copyブロックを配列に格納するときと、ブロックを使い終わったときに、ブロックで関数を使用して、ブロックをヒープに移動することができBlock_releaseます。Block_copy実行ブロック変数をヒープに移動します。これにより、アプリの実行を続けても変数がスタック メモリで上書きされません。

Block_copy の使用例。最初にブリッジキャストを行う必要があります

そのように、ヘッダーでブロックタイプの typedef を定義します。この型の例には引数がありません。

typedef void (^myBlockType)();

配列にブロックを追加する場合は、次のようにブロックをコピーできます。

- (void)addBlock:(void (^)())aBlock
{
        [mutableBlockArray addObject:(__bridge myBlockType)Block_copy((__bridge void *)aBlock)];
}

ブロックの操作が完了したら、次のように解放する必要があります (ARC では必要ありません)。

id finishBlock = [mutableBlockArray objectAtIndex:index]
Block_release((__bridge void *)finishBlock);
于 2012-11-19T21:14:26.880 に答える