2011-12-14 7 views
4

Xcode 4.2とARCを使用して、スタックからヒープにブロックをコピーする必要があるかどうかを理解する前に、次のコードを書きました。ブロック、スタック、およびヒープ

-(void) downloadWithBlock:(void (^)(void))callbackBlock; 
{ 
    // start the data download in the background... 
    NSOperation *backgroundOperation = [NSBlockOperation blockOperationWithBlock:^{ 
     // synchronous download code 
    }]; 
    [backgroundOperationQueue addOperation:backgroundOperation]; 
    NSOperation *foregroundOperation = [NSBlockOperation blockOperationWithBlock:^{ 
     callbackBlock(); 
    }]; 
    [foregroundOperation addDependency:backgroundOperation]; 
    [[NSOperationQueue mainQueue] addOperation:foregroundOperation];  
} 

コードは機能しますが、わかりませんので、私はそれを信用しません。コードの別のセクションでは、-copyを使用せずにivarsに格納されたブロックを呼び出しながら、アプリケーションのクラッシュを経験しました。ここ

-(void) downloadWithBlock:(void (^)(void))callbackBlock; 
{ 
    void(^heapBlock)(void) = [callbackBlock copy];  
    // start the data download in the background... 
    NSOperation *backgroundOperation = [NSBlockOperation blockOperationWithBlock:^{ 
     // synchronous download code 
    }]; 
    [backgroundOperationQueue addOperation:backgroundOperation]; 
    NSOperation *foregroundOperation = [NSBlockOperation blockOperationWithBlock:^{ 
     heapBlock(); 
    }]; 
    [foregroundOperation addDependency:backgroundOperation]; 
    [[NSOperationQueue mainQueue] addOperation:foregroundOperation];  
} 

私の唯一の懸念は、ブロックポインタがどのように動作するかのより良い理解を得ることである:それは、私は、コードのこのセクションでは、このように書き直されるべきかどうかを疑問にしました。これらのコードセクションのいずれかが受け入れられますか?別のブロック内でブロックを呼び出すと、コンパイラーはブロックされたBlock_copy操作を挿入しますか?

答えて

1

ブロック内のブロックの呼び出しだけでなく、ブロックへの直接参照によってコピーが発生します。他のものへの議論としてそれを渡すことを含む。同じブロック内のObjCの型になります(単純な保持であり、コピーではありません)。

+0

ありがとうございます。他のObjC型との類推は、ブロックが参照する標準のObjCオブジェクトを保持するために、ブロックがARCコンパイラをトリガーすることを理解するのに役立ちます。 –

+0

ブロックでは、ARCがなくても起こります。これは奇妙ですが、非常に便利です。また、少なくとも1つのOSリリースサイクルでARCよりも前のブロックが理解できる。 – Stripes

関連する問題