什么是block
block 与 int 、 float 等数据类型一样, block 也是一个数据类型,它可以用来声明一个数据变量。 block 类型专门用来存储一段代码,这段代码既可以有参数,也可以由返回值。
如何声明block变量
在声明一个 block 变量时,必须指定这个 block 变量的存储的代码段是否具有参数和返回值,并且一旦确定后不可更改。
声明 block 变量的格式是
// 返回值类型 (^block名称)(参数列表);
void (^MyBlock)(int a);
int (^MyBlock1)(int a, int b);
声明时可以省略参数的变量名,如:
int (^MyBlock2)(int, int);
如何初始化一个block变量
初始化一个block变量只需要写一段符合规则的代码段并赋值给变量即可。
代码段的格式:
/*
^返回值类型(参数列表){
代码段;
};
*/
^int(int a){
return a*a;
};
若一个代码段的返回值可以省略,系统会自动根据 return 的变量的类型确定返回值类型,如果没有参数可省略 (),例如:
^{
NSLog(@"我是代码段");
}
然后将代码段赋值给 block 变量即可:
int (^MyBlock)(int a);
MyBlock = ^int(int a){
return a*a;
};
注意:给 block 赋值时代码段必须符合要求,否则会报错。
用typedef定义block
因为声明 block 变量过于繁琐,当声明多个相同类型 block 变量时操作起来很麻烦。所以可以使用 typedef 定义 block 数据类型。
typedef void(^block)();
block b1;
block b2;
如何执行block
例如,我们用以下代码定义了一个 block 代码段
int (^MyBlock)(int a);
MyBlock = ^int(int a){
return a*a;
};
我们只需要直接使用 block变量名(参数); 即可直接调用,例如:
MyBlock();
block内使用外部变量
在 block 内可以直接读取到外部的变量,但是直接对外部变量进行修改会报错,例如以下情况。
int a = 20;
__block int b = 20
void (^block)(void)=^{
NSLog(@"%d %d",a,b); //此处正常输出 20 20
//a++; //此处对 a 进行自增会报错
b++; //对 b 进行自增正常运行
}
所以如果在 block 内要修改外部的变量,需要在定义变量时加上 __block。
block作为参数
既然 block 是一个数据类型,那么 block 声明的变量也可以作为参数传递。
block 变量作为函数的参数:
void test(void (^block)()){
block();
}
调用 test 函数:
test(^{
NSLog(@"我是block");
});
block 变量作为方法的参数:
-(void)doSomethingWithBlock:(int ^(blockName)(int a,int b));
调用 doSomethingWithBlock 方法:
[objectName doSomethingWithBlock:^(5,5){
NSLog(@"我是block");
}];