iCa*_*arp 14 objective-c objective-c-blocks
我知道Objective-C Block可以捕获并设置其封闭范围之外的变量值.它是如何做到的?
Jos*_*ell 25
它实际上相当简单,并在Clang的Block Implementation Spec中的"Imported Variables"部分中进行了描述.
当编译器遇到像这样的块时:
^{ if( numBalloons > numClowns) abort(); }
Run Code Online (Sandbox Code Playgroud)
它创建了一个文字结构,其中包括两个在这里很重要的元素.有一个指向块中可执行代码的函数指针,以及一个const在块内引用的每个变量的字段.像这样的东西:
struct __block_literal_1 {
/* other fields */
void (*invoke)(struct __block_literal_1 *);
/* ... */
const int numBalloons;
const int numClowns;
};
Run Code Online (Sandbox Code Playgroud)
请注意,该invoke函数将获取指向此处正在定义的类型的结构的指针; 也就是说,Block在执行代码时会自行传递.因此,代码可以访问结构的成员.
在声明之后,编译器创建了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. *
};
Run Code Online (Sandbox Code Playgroud)
然后,在invoke函数内部,对捕获的变量的引用就像结构的任何其他成员一样the_block->numBalloons.
对象类型变量的情况稍微复杂一些,但同样的原则也适用.
在块对象的代码体内,可以用五种不同的方式处理变量.
您可以引用三种标准类型的变量,就像在函数中一样:
- 全局变量,包括静态局部变量
- 全局函数(不是技术变量)
- 来自封闭范围的局部变量和参数
Blocks还支持另外两种类型的变量:
在功能级别是
__block变量.这些在块(以及封闭范围)内是可变的,并且如果将任何引用块复制到堆中,则会保留它们.
const进口.最后,在方法实现中,块可以引用Objective-C实例变量 - 请参阅对象和块变量.
以下规则适用于块中使用的变量:
可以访问全局变量,包括封闭词法范围内存在的静态变量.
传递给块的参数是可访问的(就像函数的参数一样).
封闭的词法范围本地的堆栈(非静态)变量被捕获为
const变量.它们的值是在程序中的块表达点处获取的.在嵌套块中,从最近的封闭范围捕获值.
使用
__block存储修饰符声明的封闭词法范围的局部变量由引用提供,因此是可变的.任何更改都会反映在封闭的词法范围中,包括在相同的封闭词法范围内定义的任何其他块.这些在__block存储类型中有更详细的讨论.
在块的词法范围内声明的局部变量,其行为与函数中的局部变量完全相同.
每次调用块都会提供该变量的新副本.这些变量又可以
const在块中包含的块中用作或引用变量.
从这里:http:
//developer.apple.com/library/ios/#documentation/cocoa/conceptual/Blocks/Articles/bxVariables.html
| 归档时间: |
|
| 查看次数: |
6313 次 |
| 最近记录: |