如何制作 dispatch_async nil 块

How to make dispatch_async nil out block

我正在读这个: does dispatch_async copy internal blocks

并且我想知道如何使用 dispatch-async 来清零它复制到堆上的块,以便可以对该块进行垃圾回收。

好的,所以在本地堆栈上,我创建了我的块:

MyBlock aBlock = ^{
        for (int i = 0; i < 10; i++) {
            NSLog(@"holder is: %p, holder.block is %p", holder, holder.block);
            sleep(1);
        }
    };

dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, aBlock);

sleep(2);     // give the queue some time to start executing the block

该块继续执行只是因为它是由 dispatch_async 复制的堆上的块。这都是预期的行为。

所以我的问题是....有没有办法明确地销毁堆上的这个块?

或者当 dispatch_async 完成执行时,ARC 内存是否会从堆中为我管理该块,而我个人对此无能为力?

谢谢!

您可以将 BOOL 属性 添加到 class BlockHolder 例如:

@property (nonatomic, assign, getter = isCancelled) BOOL cancelled;

并在块内添加一个测试来检查块是否被取消,如下所示:

__block BlockHolder * holder = [[BlockHolder alloc] init];
MyBlock aBlock = ^{
        for (int i = 0; i < 10; i++) {
            if(holder.isCancelled) return;
            NSLog(@"holder is: %p, holder.block is %p", holder, holder.block);
            sleep(1);
        }
    };

如果你想取消这个块,你可以将取消的值设置为是。 希望对你有所帮助

如果你想取消循环你需要在里面放一个检查并在不满足条件时跳出。这可能是您的容器对象现在为 nil,或者可能是某些方法调用的结果。只要确保您不会保留或影响您通过测试添加的测试...

对于您更新后的问题,您不需要nil任何东西。堆上的块就像任何其他引用计数对象一样。在变量 aBlock 的范围内,您的范围对它有很强的引用。并且异步调度机制在它执行之前持有对它的强引用。当不再有对它的强引用时,它就会被释放。