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

标签 ios objective-c automatic-ref-counting

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

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 或使用 __block 说明符 block 已经保留?在内存管理方面, block 和其他 Objective C 对象之间还有哪些其他潜在差异?

最佳答案

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

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

关于ios - 如果 block 在方法中的 dispatch_after 函数中使用,是否必须制作 block 的堆副本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42323230/

相关文章:

ios - 未使用结构

ios - 如何检查 S3 存储桶中的文件可用性

objective-c - 启用僵尸可以阻止我的应用程序崩溃

ios - 使用 QuartzCore 为 UITextView 创建阴影

iphone - 如何在 ios 上正确格式化货币

ios - 使用自动布局调整 UINavigationBar 高度

ios - 将 3D 网格文件放在 Camera ARKit 前面(objective-C)

ios - 以编程方式设置在 View Controller 上添加的对象的标签

ios - 即使在使用弱/强 ARC 语义时也保留循环

ios - __ block : Assigning a variable inside a block to an outside variable does not work