2017-02-19 18 views
1

Я пытаюсь сделать cancellble блок, и это мой код:ли это сделать кучу копию блока, если блок используется в функции dispatch_after в методе

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 года назад, которые, возможно, не включили недавнее изменение Apple.

Мой вопрос будет в том, что [копия блока] и копия cancelableBlock все еще необходимы в ARC? Нам еще нужно сделать копию блока или спецификатором __block, который уже сохранен? Каковы другие потенциальные различия между блоками и другими объектами-объектами с точки зрения управления памятью?

ответ

1

согласно Clang documentation вам не придется беспокоиться: __ блок переменного типа владельца могущего быть удержанного объект перемещается из стека инициализации кучи копии в результате перехода от копии стеки. Итак, ARC сделает все для вас.

Я думаю, что все это [copy] материала возникло из-за ошибки в LLVM, которая была исправлена ​​давно.