1. block是什么?
带有自动变量(局部变量)的匿名函数 。这个定义满足以下三点:
1.block是一个函数
2.block是一个没有名字的函数
3.block有参数列表,但是这个参数列表是局部变量
2. block的使用
2.1 block的语法
block经常使用省略语法,那么意味着省略了一些不必要的东西,我们一步步解析。
1.block完整语法:
^ 返回值类型 参数列表 表达式
^int (int count){ return count + 1; }
2.省略返回值类型后:
^ 参数列表 表达式
^ (int count){ return count + 1; }
3.省略参数与返回值后:
^ 表达式
^{ printf("Blocks"); }
可以看到,对比正常函数语法:
- 返回值类型 函数名 参数列表 表达式
- int name(int count) { return count + 1; }
完整语法block实际上与普通函数的区别在于,没有函数名,并使用 ^ 来表明是block函数。
2.2 block作为变量使用
block也可以作为变量使用,正常定义变量时,需要给出变量类型以及变量名,使用block也是如此。
声明block类型的变量格式如下:
返回值 ^变量名 参数
int (^blk) (int )
我们看到,block变量和正常变量区别在于,多了返回值,以及参数。那我们又该如何赋值呢?
block变量赋值方式:
变量 = 具体block语法
int (^blk) (int ) = ^int (int count){ return count + 1; }
这很好理解,block变量也是block类型,赋值时一定也是等于具体的block。
这里,我们来讲一些block作为变量使用的方式,
1.通过Typedef 在函数参数和返回值中使用Block变量:
首先要定义 typedef int(^blk_t)(int)
block作为函数参数 void func(blk_t blk){ }
block作为函数返回值 blk_t func(){ }
2.
typedef int(^blk_t)(int);
blk_t blk = ^(int count){return count + 1};
int result = blk(10);
2.3 block截获自动变量值
1.“带有自动变量值”在Blocks中表现为“截获自动变量值”,在Block被赋值时获取当时的变量值并在以后使用。
int value = 2;
void (^block)(void) = ^{
NSLog(@"%i",value);
};
value = 10;
block(); //输出 2
2.未添加__block的情况下:截获OC对象,调用变更对象的方法不会有问题,因为block内会截获该对象的结构体实例指针.但是不能对该对象进行赋值操作
id array = [[NSMutableArray alloc] init];
void (^blk) (void) = ^{
id obj = [[NSObject alloc] init];
[array addObject:obj];//这是可行的
array = [[NSMutableArray alloc] init];//这是不可行的
}
2.4 _ _block说明符
若想在Block的表达式中将值赋给外部声明的自动变量,需要在该自动变量上附加__block
__block int value = 2;
void (^block)(void) = ^{ value = 10; };
block();
NSLog(@"%i",value);//输出10