我知道一个Objective-C块可以捕获并设置其封闭范围之外的变量值。它是如何做到的?块如何捕获其封闭范围之外的变量?
回答
在块对象的代码体中,可以用五种不同的方式处理变量。
您可以参考三个标准类型的变量,就像你从一个函数将:
- 全局变量,包括静态当地人
- 全局函数(这在技术上不变量)
- 地方来自封闭示波器的变量和参数
块还支持两种其他类型的变量:
在功能级别是
__block
变量。这些在块(和封闭范围)内是可变的,并且如果任何引用块被复制到堆中,它们将被保留。
const
进口。最后,方法的实现中,块可以参考物镜-C实例变量 - 请参见对象和块的变量。
以下规则适用于一个块中使用的变量:
全局变量是可访问的,包括存在的封闭词法范围内的静态变量。
传递给块的参数是可访问的(就像函数的参数一样)。
将封闭词法作用域本地的栈(非静态)变量作为
const
变量捕获。它们的值取自程序中块表达式的位置。在嵌套块中,该值是从最近的封闭范围捕获的。
由
__block
存储修饰符声明的封闭词法范围的局部变量由引用提供,因此可以修改。任何更改都反映在封闭词法作用域中,包括在同一个封闭词法作用域内定义的任何其他块。这些在__block存储类型中有更详细的讨论。
在块的词法范围内声明的局部变量,其行为与函数中的局部变量完全相同。
块的每次调用都会提供该变量的新副本。这些变量可以用作
const
或块中封闭块中的引用变量。
它实际上相当简单,在锵的模块实现规格说明,在"Imported Variables"部分。
当编译器遇到一个像座:
^{ if(numBalloons > numClowns) abort(); }
它会创建一个文本结构,包括 - 除其他事项外 - 在这里是很重要的两个元素。有一个指向块中可执行代码的函数指针,并且在块内引用每个变量的const
字段。事情是这样的:
struct __block_literal_1 {
/* other fields */
void (*invoke)(struct __block_literal_1 *);
/* ... */
const int numBalloons;
const int numClowns;
};
注意,invoke
功能将一个指向真实被定义在这里的那种结构;也就是说,Block在执行代码时自动进入。因此,代码可以访问结构的成员。
权的声明之后,编译器创建的模块,简单的使用引用变量初始化在struct
正确的字段的定义:
struct __block_literal_1 __block_literal_1 = {
/* Other fields */
__block_invoke_2, /* This function was also created by the compiler. */
/* ... */
numBalloons, /* These two are the exact same variables as */
numClowns /* those referred to in the Block literal that you wrote. *
};
然后,invoke
函数内部,引用到捕获的变量与结构的其他任何成员一样,the_block->numBalloons
。
对象类型变量的情况稍微复杂一点,但同样的原则适用。
基本上,对于每个捕获的本地变量,块“对象”在块对象中包含一个变量(如块对象的“实例变量”)。 (Josh Caswell的答案提供了有关如何实现的更多细节。)创建块时,此时每个捕获的局部变量的值将被复制到块内的相应变量中。只要变量在块内部使用,它就会在块内使用该变量。
- 1. 封闭本地范围变量与全局范围变量 - Python
- 2. 在封闭范围内修改变量
- 3. 封闭范围
- 4. 在封闭范围
- 5. 我如何获得编译指令来侦听其范围之外的变量?
- 6. 块内外的变量范围
- 7. JavaScript关闭 - 评估()和捕获变量在Eval()的范围
- 8. 在jquery范围之外的alert变量
- 9. 在范围变量中捕获单元
- 10. javascript中的封闭范围
- 11. 在最接近的外部范围中捕获变量
- 12. 在其范围外使用变量
- 13. 从其范围外访问变量?
- 14. 尝试捕获块变量超出范围
- 15. 访问其范围之外的变量值
- 16. 为什么scala try块允许重新定义封闭范围的变量?
- 17. 与lambda函数Python中封闭的范围变量
- 18. 从嵌套函数的封闭范围访问变量
- 19. 在封闭范围内更新变量的SSA表示
- 20. NameError:在封闭范围内赋值之前引用的自由变量'ar'
- 21. Python:NameError:在封闭范围内赋值之前引用的自由变量're'
- 22. Python:在封闭范围内赋值之前引用的自由变量'numpy'
- 23. Python的封:写入变量父范围
- 24. 关闭范围内的捕获函数
- 25. 如何在当前范围/块之外定义一个常量?
- 26. 变量在其范围之外不可见
- 27. 如何更新XMLHttprequest之外的范围变量
- 28. 我该如何更新$范围之外的控制器变量。
- 29. 如何在Go模板中分析范围之外的变量?
- 30. 如何在javascript中访问当前范围之外的变量?
我认为它基本上对待它,就好像外部变量不超出范围时,他们被定义的范围结束,使用块很多,但我不会算作自己的专家 – Fonix