12

^block を辞書または配列に格納できますか?

通知を処理するためのブロックを提供する必要があるサーバー通知をリッスンする必要があります。私のプロジェクトでは、いくつかのビュー コントローラーがすべて通知を聞きたいので、サーバーを処理するための独自のブロックを持つ汎用通知マネージャーを作成しました。通知とデリゲートの配列があるため、マネージャーのブロックで:

- (^)(NSString *message){
    for (delegate in allDelegates)
    {
        delegate.handlerBlock(message);
    }
}

しかし、ブロックをコレクションに保存できますか?

4

3 に答える 3

12

オブジェクトをコレクションに格納できます。ただし、スコープに注意してください。関数のスコープ外にある場合は、それらをコピーしてください。それらを配列に格納しているため、これがあなたのケースです。

[NSArray arrayWithObject: 
[[^{ NSLog(@"block 1"); } copy] autorelease],
[[^{ NSLog(@"block 2"); } copy] autorelease], nil]

ARC では、ブロックを絶対にコピーする必要があることを伝える必要があります。配列が解放されると、ブロックを解放する必要があります。

  [NSArray arrayWithObject: 
    [^{ NSLog(@"block 1"); } copy],
    [^{ NSLog(@"block 2"); } copy], nil]
于 2012-10-24T07:38:45.300 に答える
5

ブロックは、他のオブジェクトを保持する必要があるほとんどの場合にコピーする必要があるという点で特別です。これは、ブロックがスタック (「スタック ブロック」) で開始され、ブロックが定義されたローカル スコープでのみ有効であるためです。スタック ブロックをコピーするとヒープ ブロックが生成され、通常のオブジェクトのように動的な有効期間が設定されます。ヒープ ブロックをコピーしてもそのまま保持されるため、ブロックを長期間保持する必要がある場合は常にブロックをコピーするのが適切です。

現在、ブロック引数を取る関数は、通常、必要に応じてブロックをコピーする責任を負います。したがって、これらの関数にブロックを渡すときに特別なことをする必要はありません。ただし、この場合[NSArray arrayWithObject:]、通常のオブジェクト引数を取る にブロックを渡しています。ブロック引数を取らないため、引数をコピーすることを知らず、そのまま保持します。したがって、通常のオブジェクト引数を取るメソッドにブロックを渡すときは、最初にそれをコピーする必要があります。

于 2012-10-24T18:45:14.170 に答える
-1

ここの非常に優れた記事を読めば、これを行う方法がわかります。そして、そこで言及されている「最初にスタックからコピーする」というイディオムに特に注意してください。

于 2012-10-24T07:33:56.313 に答える