我正在尝试制作一个取消 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/