2011-01-10 5 views
1

dispatch_syncブロックで内容が設定された配列を返したいと思います。私は完全な配列のコピーをしているが、代わりに一つ一つを追加したい、私は「自動解放をスキップすることができていないよ場合__blocksとdispatch_sync内でオブジェクトを割り当てる

-(NSArray *)getSomeLockedList { 

    __block NSArray *resultList; 

    dispatch_sync(myQueue, ^{ 
     // copy contents of my ivar NSMutableArray into return variable 
     resultList = [ivarContentList copy]; 
    }); 

    // add auto-release since a 'copy' was done within block 
    return [resultList autorelease]; 
} 

私は一般的に見てきたコードは次のようなものです'戻り値ですか?スタックはこの方法のために完了した後

-(NSArray *)getSomeLockedList { 

    __block NSArray *someResultKeys; // is it ever safe to do the alloc here? 

    dispatch_sync(myQueue, ^{  
     someResultKeys = [NSMutableArray array]; 

    for (id entry in ivarContentList) { 

      // do some work on entry instance 
      [someResultKeys addObject:entry];  
     }   
    }); 

    return someResultKeys; // autorelease not necessary? 
} 

結果の継続的な使用のためのdispatch_syncブロック内の安全[NSMutableArrayの配列】割当か?

答えて

3

いいえ、これは安全ではありません。問題は、キューにディスパッチするときに、そのキューのオートレリースされたオブジェクトは、そのキューのNSAutoreleasePoolが排水されたときに収集されるということです。あなたはこれがいつ行われるかを支配しません。これについて考える適切な方法は、ブロックがキューで実行を完了した瞬間にオートリリースプールが排除されると常に仮定することです。

あなたのケースでこれを処理するための正しい方法はキューに

someResultKeys = [[NSMutableArray alloc] init]; 

を使用して、dispatch_sync後[someResultKeys autorelease]を呼び出すことです。

+2

ブロックの前に変更可能な配列を作成し、ブロック内の項目を追加するだけです。その場合、 'someResultsKey'はブロック内で変更されないので' __block'宣言する必要はありません。 –

+0

@ダニエルそれはおそらくこの特定のケースでは、それについて行くためのより良い方法です。 –

0

これは単にブロックの外側

NSMutableArray* someResultKeys = [NSMutableArray array]; 

を書き込むことによって__block変数を避けてはるかに容易に行われます。しかし、私はdispatch_syncについて不思議です。 dispatch_syncは、ブロックの実行が完了するまで待機します。 (また、シリアルキューの場合は、ブロックが実行を終了する前にすべてのブロックを意味します)。コードを直接呼び出さない理由はありますか?

関連する問題