iOS中block简介-作用域
-
用block可以定义任意的代码片段,将其像对象一样传入另一个方法;它是c级别的语法,和C语言中的函数指针非常相似。在C语言中,函数指针和block写法分别如下
12int
(* func1)(
int
a,
int
b);
//c函数指针
返回类型 | 函数名 | 参数
12int
(^backValue)(
int
num);
//block
返回类型 | 方法名 | 参数
block对象也是对象,实例化方法如下
123int
(^backValue)(
int
) = ^(
int
num) {
return
num+
1
;
};
block需要注意的一个特性就是"Variable Capturing",直译过来就是捕捉变量。block会将“捕捉”到的变量复制一份,然后对复制品进行操作,这是非常重要的一点。对于以下代码来说打印结果是b-->2,这是因为在block作用域内会复制a,然后对复制的a进行操作,作用域外的a就不会产生变化,所以,在a++;之后再调用backValue(1),结果是2
1234567int
a =
1
;
int
(^backValue)(
int
) = ^(
int
num) {
return
num+a;
};
a +=
1
;
int
b = backValue(
1
);
NSLog(@
"b-->%d"
, b);
如果希望block作用域内可以修改外边的变量,可以使用__block(注意是两个下划线)来修饰int a。这样以来结果就会是b-->3。刚才的例子中a是一个基本类型的变量,如果block外是一个oc对象的话,结果就又不一样了,比如下边代码,结果就是"block作用域内赋值"
1234567UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(
10
,
300
,
300
,
40
)];
label.text = @
"block作用域外赋值"
;
void
(^backValue)(NSString *) = ^(NSString *str) {
label.text = str;
};
backValue(@
"block作用域内赋值"
);
[self.view addSubview:label];
这是因为UILabel *label;定义了一个对象指针,在block作用域内复制的是label这个指针,而不是对象,复制之后的指针仍然指向原来的对象,所以对label.text进行操作是可以修改原对象的,但是作用域内如果想下边这样写就不行了,会得到提示Variable is not assignable。1label = [[UILabel alloc] init];