我正在读这个: 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内存是否会从堆中为我管理该块,我个人无法对此做任何事情?
谢谢!
答案 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
的范围内具有强烈的引用范围。并且异步调度机制在执行之前会持有强引用。如果没有强烈的引用它,它就会被释放。