2017-02-19 3 views
1

にdispatch_after機能で使用されている場合、それは私がcancellbleブロックを作るしようとしていますと、これは私のコードであるブロックのヒープコピーを作成する必要がない:ブロックは方法

typedef void(^dispatch_cancelable_block_t)(BOOL canceled); 

dispatch_cancelable_block_t dispatch_after_with_cancel(NSTimeInterval delay, dispatch_block_t block) { 
    if (block == nil) { 
     return nil; 
    } 

    __block dispatch_block_t originalBlock = [block copy]; 
    __block dispatch_cancelable_block_t cancelableBlock = [^(BOOL canceled){ 
     if (!canceled && originalBlock) { 
      originalBlock(); 
     } 
     originalBlock = nil; 
    } copy]; 

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ 
     if (cancelableBlock) { 
      cancelableBlock(NO); 
      cancelableBlock = nil; 
     } 
    }); 

    return cancelableBlock; 
} 

とブロックこの機能を使用してキャンセルすることができます。

void cancel_block(dispatch_cancelable_block_t block) { 
    if (block == nil) { 
     return; 
    } 
    block(YES); 
    block = nil; 
} 

私はしばらくの間、検索しましたが、私が得たすべてがアップルの最近の変更が含まれていない可能性がある3または4年前に書かれました。

私の質問は、ARCで[ブロックコピー]とcancelableBlockのコピーが必要ですか?ブロックのコピーを作成する必要がありますか?ブロックが既に保持されている__block指定子を使用していますか?メモリ管理に関して、ブロックと他の目的のCオブジェクトとの間の他の潜在的な違いは何ですか?

答えて

1

Clang documentationによると、あなたは心配する必要はありません。保持できるオブジェクト所有者タイプの __ブロック変数がスタックのコピーから移動した結果でヒープコピーを初期化することによって、スタックから移動されています。 したがって、ARCはあなたのためにすべてを行います。

私はこのすべてを考えるとLLVMのいくつかのバグが長い間修正されています。

関連する問題