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

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

为了使 block 能够工作,可以保留它们必须访问堆栈帧的局部变量。

因为框架必须在函数退出后继续存在,所以我假设该 block 处理的是原始堆栈框架的副本。

栈帧保留一个 block 还是 block 保留栈帧?

队列是否保留其中的 block ?

最佳答案

block 不保留栈帧。 block 引用的堆栈变量在堆栈上被引用,直到 block 被移动到堆中。那时,任何自动变量都与 block 一起复制,并且所有 __block 变量都被复制到堆中。

参见 Blocks and Variables在 block 编程主题中了解详细信息。

栈帧不保留任何东西,也没有任何东西保留栈帧。堆栈帧不能“做”任何事情(它们只是偏移到堆栈中)。而且没有什么可保留的(它们只是堆栈中的偏移量)。堆栈框架无法在其作用域退出后继续存在。

队列有效地保留添加到它们的 block (并且 block 有效地保留它们的队列直到它们被执行)。我所说的“有效”只是指“有一个强大的引用可以防止它被破坏”。这是否实际通过调用 objc_retain 实现是一个实现细节。

编辑:最后一段可能比它阐明的更令人困惑。调用 dispatch_async 实际上是“复制” block ,而不是保留它。但是这里的“复制”一词与它对其他对象的含义并不完全相同。它实际上是指将 block 从堆栈移动到堆,您的面试官可能正在探索 MRC 问题,即您不保留要保留的 block ,而是复制它们。但在 ARC 中,这已经隐藏起来,最好从强引用的角度考虑它,这正是我希望表达的观点。当您调用 dispatch_async ,它会自动为您处理复制 block ,并在完成时释放 block (这是记录在案的行为;请参阅链接;这对于 MRC 和 ARC 都是如此)。因此,当它在队列中时,您不必维护对 block 的单独引用以将其保留在周围(这会非常不方便)。

在执行 block 之前, block 还保持对队列的引用这一事实记录在 dispatch_queue_create 中。 .

关于iOS: block 是否保留堆栈框架?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51699051/

相关文章:

ios - 有没有办法比较CGPoints?

ios - iPhone - 选择后 UITableViewCell 为白色

ios - 绝对初学者应该从哪里开始?

ios - 使用NSLayoutConstraint时引起的编译错误

ios - 屏幕周围的动画 MapView

ios - 为什么在 ObjectiveC 中参数前面有一个 "_"?

iphone - 如何将 viewController 放入 UIScrollView 中

swift - Mac Catalyst 上的应用内购买不起作用

bash - shell 脚本 (macOS) : print escaped Unicode character from a plist string

UITableView 上的 iOS didSelectRowAt 行不起作用