如何使dispatch_async nil out block

时间:2015-09-11 11:44:43

标签: ios block dispatch-async

我正在读这个: 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内存是否会从堆中为我管理该块,我个人无法对此做任何事情?

谢谢!

3 个答案:

答案 0 :(得分:0)

您可以将BOOL属性添加到类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);
        }
    };

如果要取消阻止,可以将取消值设置为YES。 我希望它会对你有所帮助

答案 1 :(得分:0)

如果您希望能够取消循环,则需要在内部进行检查,并在不满足条件时将其中断。这可能是您的容器对象现在为零,或者它可能是某些方法调用的结果。请确保您没有通过测试来保留或影响您添加的测试......

答案 2 :(得分:0)

对于您的更新问题,您无需nil任何内容。堆上的块就像任何其他引用计数对象一样。您的范围在变量aBlock的范围内具有强烈的引用范围。并且异步调度机制在执行之前会持有强引用。如果没有强烈的引用它,它就会被释放。