如果块在方法中的 dispatch_after 函数中使用,是否必须制作块的堆副本

Does it have to make a heap copy of a block if the block is used in a dispatch_after function in a method

我正在尝试创建一个取消块,这是我的代码:

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;
}

我找了一段时间,但我得到的都是三四年前写的,可能没有包括苹果最近的变化。

我的问题是 [block copy] 和 cancelableBlock 的副本在 ARC 下仍然需要吗?我们是否还需要复制块或使用 __block 说明符块已经保留?在内存管理方面,块和其他 objective c 对象之间的其他潜在差异是什么?

根据 Clang documentation,您不必担心: __ retainable object owner 类型的块变量通过使用从堆栈副本中移出的结果初始化堆副本而移出堆栈。 所以ARC会为你做一切。

我认为所有这些 [copy] 东西都源于 LLVM 中的一些错误,该错误早已修复。