在block代码块中,可以引用的变量和函数没有区别。有以下几种:
1.全局变量,包含静态static变量。
2.全局函数(也可以当做一种变量引用)。
3.局部变量和参数。
除了上面3种,block代码块还支持两种变量:
1.函数级的__block变量。__block变量可以在block代码块中被改变。如果block代码块的引用被拷贝,__block变量将被保留,不被释放。
2.引入的const变量。
概念:堆heap 栈stack
block代码块中的变量有以下规则:
1.可以访问全局变量,包含静态变量。
2.可以访问传给block的参数,和函数的参数一样。
3.局部变量,不管存放在栈里还是堆里,都被当做const常量。这些变量的值是block定义的地方的值。它们是以值的形式传的,而不是以地址传的,所以不能改变值。
4.以__block修饰的局部变量,传人block时,传的是引用,而不是值,所以可以改变它的值。可以在block里嵌套的block里被改变。
5.block里面定义的局部变量,和函数中定义的局部变量表现一样。
__block存储类型
1.以__block修饰符修饰的变量,可以在block代码块中被改变其值。__block可以在上下文和该范围中所有的block中共享。
2.如果使用Block_copy或者直接copy block,变量也会被拷贝到堆里,这样的话,__block变量也有了新的拷贝。
__block变量的限制:
1.不能用于修饰可变长度的数组。
2.不能用于修饰有可变长度数组的结构体。
对象和block变量
block代码块支持Obj-C,C++对象和其他block作为变量。
Objective - C对象:
当block被拷贝,block里面的变量也被创建了强引用。如果在函数中使用block:
1.如果访问实例变量的地址引用,会生成一个对self的强引用。
2.如果范围实例变量的值,会生成一个对该实例变量的强引用。
dispatch_async(queue, ^{
//instanceVariable is used by reference, a strong reference is made to self.
doSomethingWithObject(instanceVariable);
});
id localVariable = instanceVariable;
dispatch_aync(queue, ^{
//localVariable is used by value, a strong reference is made to localVariable (and not to self).
doSomethingWithObject(localVariable);
});
C++对象:
block中使用的C++成员函数和成员变量引用,会隐式的通过this变量传人,所以它们是可以被改变的。
有两个规则:
1.对基于C++堆栈的对象,__block修饰时调用通常的copy构造函数。
2.没有__block修饰的基于C++堆栈的对象,必须有一个const的copy构造函数,block会调用该const的copy构造函数。
Blocks:
1.如果copy一个block,该block中嵌套的block都会被依次copy.
2.如果有一个block,并且该block中引用了另一个block,则被引用的block会被copy.