代码块本质上是和其他变量类似。不同的是,代码块存储的数据是一个函数体。使用代码块是,你可以像调用其他标准函数一样,传入参数数,并得到返回值。
脱字符(^)是块的语法标记。按照我们熟悉的参数语法规约所定义的返回值以及块的主体(也就是可以执行的代码)。下图是如何把块变量赋值给一个变量的语法讲解:
block可以帮助我们组织独立的代码段,提高复用性和可读性
按照调用函数的方式调用块对象变量就可以了:
int result = myBlock(5); // result是 35;
void (^printBlock)(NSString *x);
printBlock = ^(NSString* str)
{
NSLog(@"print:%@", str);
};
printBlock(@"hello world!");
在ios,blocks是对象,它封装了一段代码,这段代码可以在任何时候执行。Blocks可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。它和传统的函数指针很类似,但是有区别:blocks是inline的,并且它对局部变量是只读的
Block可以访问局部变量,但是不能修改。比如下面的代码就会报编译错
int num = 0;
//使用block
int (^myBlock) (int a,int b) = ^(int a,int b){
num = a+b;
return num;
};
如果要修改就要加关键字:__block (注意,是两个下划线"_")
__block int num = 0;
//使用block
int (^myBlock) (int a,int b) = ^(int a,int b){
num = a+b;
return num;
};
- void(^block)(int a) = ^{
- NSLog(@"I'm a block! a = %i", a);
- };
而下面的代码是从block中返回一个值:
- int(^block)(void) = ^{
- NSLog(@"I'm a block!");
- return 1;
- };
作为一个封闭的包,block将所处的上下文封装到了block中:
- int b = 1;
- void(^block)(void) = ^{
- NSLog(@"I'm a block! a = %i", b);
- };
作为函数的参数,blocks某种意义上替代了回调函数或者delegate。当函数调用了,假设某个事件触发,这时block里的内容就会运行。这样有利于代码的整合和阅读,你不需要到处去实现委托方法了。
总结
Block不仅提供了C函数同样的功能,而且block看起来更加直观。block可以定义为内联(inline),这样在函数内部调用的时候就非常方便,由于block具有闭包性(closure),所以block可以很容易获得上下文信息,而又不会对这些数据产生负面影响。