iOS:块是否保留堆栈框架?

时间:2018-08-05 23:39:36

标签: ios iphone macos grand-central-dispatch objective-c-blocks

为了使块能够工作,它们必须保留局部变量,它们必须有权访问堆栈框架。

由于该框架必须在函数退出后仍然存在,所以我认为该块要处理的是原始堆栈框架的副本。

堆栈框架是否保留一个块或该块保留了堆栈框架?

队列是否保留其中的块?

1 个答案:

答案 0 :(得分:2)

块不保留堆栈框架。由块引用的堆栈变量在堆栈上被引用,直到将块移到堆中为止。那时,所有自动变量都将与块一起复制,并且所有__block变量都将复制到堆中。

有关详细信息,请参见块编程主题中的Blocks and Variables

堆栈框架不会保留任何内容,也不会保留堆栈框架。堆栈帧无法“做”任何事情(它们只是偏移到堆栈中)。而且没有什么可保留的(它们只是偏移到堆栈中)。堆栈框架无法幸免于它们的作用域。

队列有效保留添加到队列中的块(并且块有效保留其队列直到执行)。 “有效地”我的意思是“有一个强有力的参考可以防止其被破坏”。这是否通过调用objc_retain来实现,这是实现细节。

编辑:最后一段可能比它所阐明的更加混乱。实际上,调用dispatch_async会“复制”该块,而不是保留它。但是,此处的“复制”一词与其他对象的含义并不完全相同。这实际上是指将一个块从堆栈移动到堆,您的访问员可能正在探索MRC问题,即您没有保留要保留的块,而是将其复制。但是在ARC中,这已经悄悄地进行了,最好从强引用的角度来考虑它,这就是我希望提出的观点。当您调用dispatch_async时,它会自动为您复制该块,并在完成时释放该块(这是记录的行为;请参见链接;对于MRC和ARC都是如此)。因此,您无需维护对块的单独引用即可在块处于队列中时将其保留(这非常不方便)。

dispatch_queue_create中记录了在执行之前,块还保持对队列的引用。