如果在方法

时间:2017-02-19 03:13:56

标签: ios objective-c automatic-ref-counting

我正在尝试制作一个可取消的块,这是我的代码:

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 个答案:

答案 0 :(得分:1)

根据Clang documentation你不必担心: 通过使用从堆栈副本移动的结果初始化堆副本,将__ 可保留对象所有者类型的块变量移出堆栈。 所以ARC会为你做一切。

我认为所有这些[copy]内容都源于很久以前修复过的LLVM中的一些错误。