假设我有一个具有深度绑定的静态/词法范围语言,并且我创建了一个闭包。闭包将包括我想要执行的语句以及所谓的引用环境,或者引用这篇文章,可以使用的变量集合。
这个引用环境在实现方面实际上看起来像什么?我最近在阅读有关 ObjectiveC 块的实现的内容,作者建议在幕后您可以获得堆栈上所有变量的副本以及对堆对象的所有引用。该解释声称您在创建闭包时获得了引用环境的“快照”。
- 或多或少会发生这种情况,还是我误读了?
- 是否采取任何措施来“冻结”堆对象的单独副本,或者假设如果它们在闭包创建和闭包执行之间被修改,闭包将不再在对象的原始版本上运行?
- 如果确实进行了复制,那么在可能想要创建大量闭包并将它们存储在某处的情况下是否有内存使用注意事项?
我认为对其中一些概念的误解可能会导致棘手的问题,例如 Eric Lippert 在这篇博文中提到的问题。这很有趣,因为您会认为保留对在调用闭包时可能已经消失的值类型的引用是没有意义的,但我猜在 C# 中编译器会找出变量稍后需要并将其放入堆中。
似乎在大多数内存管理的语言中,一切都是引用,因此 ObjectiveC 是一个有点独特的情况,必须处理复制堆栈上的内容。