【Objective-C高级编程】iOS与OS X多线程和内存管理(三) Block语法

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语言数组的截获。使用指针可以解决这个问题。


你可能感兴趣的:(【Objective-C高级编程】iOS与OS X多线程和内存管理(三) Block语法)