一、Blocks概要
二、Blocks模式1、什么是Blocks
blocks是C语言的扩充功能,可以用一句话来表示blocks的扩充功能:带有自动变量(局部变量)的匿名函数;
顾名思义,所谓匿名函数就是不带有名称的函数
1、block语法
^(int event){ printf("buttonid:%d evaent=%d\n", i, event); } //实际上,该block语法使用了省略方式,其完整形式如下: ^void (int event){ printf("buttonid:%d event=%d", i, event); }
如上所示,完整形式的block语法与一般的C语言函数定义相比,仅有两点不同:
- 没有函数名;
- 带有“^”符号;
“返回值类型”同C语言函数的返回值类型一样,“参数列表”同C语言的参数列表一样,“表达式”同C语言函数中允许使用的表达式一样。当然与C语言函数一样,表达式中含有return语句时,其类型必须与返回值类型相同;
//完整的block语句 ^int (int count){return count + 1;}
block语法可省略好几个项目,首先是返回值类型:
省略返回值类型时,如果表达式中有return语句就是用该返回值类型;如果没有return语句就是用void类型;表达式中含有多个return语句时,所有return语句的返回值类型必须相同;
如果不使用参数,参数列表也可省略。以下为不使用参数列表的block语法:
^void (void){printf("Blocks");} //该源代码可省略为如下形式: ^{printf("Blocks");}
2、block类型变量
在定义C语言函数时,可以将所定义函数的地址赋值给函数指针类型变量中:
int function (int count){ return count + 1; } int (*funcptr)(int) = &function;//这样一来,函数function的地址就能赋值给函数指针类型变量funcptr中;
在block语法下,可将block语法赋值给声明为block类型的变量中,即源代码中一旦使用饿了block语法就相当于生成了可赋值给block类型变量的值;在block语法中,block生成的值也被称为block;
声明block类型变量的示例如下:
int (^blk)(int);
block类型变量与一般的C语言变量完全相同,可做用途如下:
- 自动变量(局部变量)
- 函数参数
- 静态变量
- 静态全局变量
- 全局变量
使用block语法将block赋值为block类型变量:
int (^blk)(int) = ^int (int count){return count+1;};
//在函数中,使用block类型变量作为函数的参数传递 void function(int (^blk)(int)){} //在函数返回值中指定block类型,使用block作为函数返回值 int (^function() (int)){ return ^(int count){return count;};
使用typedef解决block类型命名问题://使用typedef解决block类型命名问题: typedef int (^blk_t)(int); //如上所示,通过使用typedef可声明"blk_t"类型; //原来的记述方式 void function(int (^blk)(int)){} //使用typedef类型 void function(blk_t blk){} //原来的记述方式 int (^func()(int)){} //使用typedef类型 blk_t func(){}
//变量blk为block类型的情况下,这样调用block类型变量: int result = blk(10); //在函数参数中使用block类型变量并在函数中执行block的例子: int function(blk_t blk, int rate){ return bulk(rate); }
//block类型变量和完全像C语言变量一样使用,因此也可以使用指向block类型变量的指针,即block的指针类型变量: typedef int(^blk_t)(int); blk_t blk = ^(int count){return count+1;}; blk_t *blkptr = &blk; (*blkptr)(10);
定义和使用block:
//第一种,无参数无返回值的block void (^myBlock)() = ^(){}; //第二种,有参数无返回值的block void (^myBlock)(int) = ^(int count){}; //第三种,有参数有返回值的block int (^myBlock)(float) = ^int(float number){};
block语法总结:
- 在类中定义一个block变量,就像定义一个C语言函数;
- block变量可以定义在viewDidLoad函数外部,也可以定义在内部;
- 只有调用block变量时,{}内部的代码才会执行;
3、截获自动变量值
4、__block说明符
int val = 0; void (^blk)(void) = ^(){val = 1;}; blk(); printf("val = %d\n", val); //以上为在block语法外声明的给自动变量赋值的源代码,该源代码会产生编译错误;
//如果想在block语法的表达式中将值赋给在block语法外声明的自动变量,需要在该自动变量上附加__block说明符; __block int val = 0; void (^blk)(void) = {val = 1;}; blk(); printf("val = %d\n", val); //执行结果为:val = 1
5、截获的自动变量
虽然赋值给截获的自动变量array的操作会产生编译错误,但是使用截获自动变量的值却不会有任何问题;
三、blocks的实现
1、block的实质
2、截获自动变量值
3、__block说明符
4、block存储域
5、__block变量存储域
6、截获对象
7、__block变量和对象
8、block循环引用
9、copy/release