1.
Block 就是带有自动变量值的匿名函数。
Block 语法的简单示例:
^void ( int enent ) {
printf("buttonId:%d, event=%d",i,event);
}
完整形式的Block语法与一般的C语言函数定义对比,仅有两点不同:
① 没有函数名。
② 带有"^".(caret) 使用插入记号便于搜索。
2. ^ 返回值类型 参数列表 表达式
3. BN范式:
Block_literal_expression ::= ^ block_decl compound_statement_body
block_decl ::=
block_decl ::= parameter_list
block_decl ::= type_expression
4. 可省略 返回值类型 。表达式中含有多个return语句时,所有return的返回值类型必须相同。
若无参数列表,参数列表亦可省略。 ^{}
5. 声明Block类型变量的示例:
int (^blk)(int);
block变量与C语言变量相同。包含:自动变量、函数参数、静态变量、静态全局变量、全局变量。
6. 赋值
int (^blk)(int) = ^(int count){ return count +1; };
//
int (^blk)(int) = blk1;
//
int (^blk)(int);
blk = blk2;
7. 在参数中可以使用Block类型变量向函数传递Block
void func (int (^blk)(int))
{
}
8. 在函数返回值中指定Block类型。
int (^func ()) (int)
{
return ^(int count){return count + 1;};
}
9. 使用 typedef 来简化书写
// 定义
typedef int (^blk_t)(int);
// 原先的写法
void func (int (^blk)(int))
// 改写
void func (blk_t blk)
// 原先的写法
int (^func()(int))
// 改写
blk_t func()
10. 截获自动变量值
int main ()
{
int dmy = 256;
int val = 10;
const char *fmt = "val = %d";
void (^blk)(void) = ^{ printf(fmt,val);};
val = 2;
fmt = "These values were changed. val = %d";
blk();
return 0;
}
//
val = 10
Block 表达式截获所使用的自动变量值,即保存该自动变量值的瞬间值。
11. __block 说明符
int val = 0;
void (^blk)(void) = ^{ val = 1;};
// 编译报错
blk();
若想在Block语法的表达式中将值赋给Block语法外声明的自动变量,需要在该自动变量上加上 __block 说明符。
int val = 0;
void (^blk)(void) = ^{ val = 1;};
blk();
// val 的值为1
// 以下代码不会编译出错
id array = [[NSMutableArray alloc] init];
void (^blk)(void) = ^{
id obj = [[NSObject alloc] init];
[array addObject:obj];
};
12. 使用C语言数组时必须小心使用其指针:
const const text[] = "hello";
// 编译出错
void (^blk)(void) = ^{
printf("%c ",text[2]);
};
const const *text = "hello";
// 编译正常
void (^blk)(void) = ^{
printf("%c ",text[2]);
};
这是因为block中,截获自动变量值的方法并没有实现对c语言数组的截获。使用指针可以解决这个问题。