block:代码块,是将一个函数作为值赋予变量。也就是说,block在本质上和其他变量类似,只是它的值是一个函数。在使用block的时候,也就可以像使用标准函数一样,可以有参数,可以有返回值。
脱字符(^)是块的语法标识。
int i = 3;
int(^myBlock)(int) = ^(int num){
return num * i;
};
int res = myBlock(4);
printf("%d\n", res);
上面的代码就是定义一个block,然后调用。
代码中,定义了一个名为myBlock的代码块,在定义block的时候,出现了3个int,第一个int是代码块的返回值类型,第二个int是形式参数类型,第三个int是实参的数据类型。从上面来看,声明一个代码块是很简单的。下面我们在来写几个没有参数,没有返回值的代码块:
没有参数的代码块:
//无参数的代码块
int (^myBlock1)(void) = ^(void){
return 10;
};
//代码块调用
int res1 = myBlock1();
//打印输出结果
printf("%d\n", res1);
没有返回值的代码块:
//无返回值的代码块
void(^myBlock2)(int) = ^(int num1){
printf("%d\n", num1);
};
//代码块调用
myBlock2(5);
block的基本定义和使用就这么多,下面我们来看看block使用局部变量和全局变量的时候会有怎么样的状况。
还是上面的代码:
int i = 3;
int(^myBlock)(int) = ^(int num){
return num * i;
};
int res = myBlock(4);
printf("%d\n", res);
这是一个代码块,这段代码没有任何问题,打印出的结果是12;现在我们对这个代码块进行一下修改:
int i = 3;
int(^myBlock)(int) = ^(int num){
return num * i++;
};
int res = myBlock(4);
printf("%d\n", res);
从上面的这个图片可以看到,我们只是在代码块中对局部变量进行了修改,这个时候,编译器会报错,而错误原因是缺少__block来修饰局部变量。将代码改为如下即可:
__block int i = 3;
int(^myBlock)(int) = ^(int num){
return num * i++;
};
int res = myBlock(4);
printf("%d\n", res);
我们发现在代码块中使用局部变量进行计算的时候是不会报错的,但是当我们要修改局部变量的时候,就会发生报错。所有,在代码块中,不可以修改局部变量。那么,全局变量又会有怎么样的情况发生呢?下面我们来写代码求证下:
int j = 9;
int main(int argc, const char * argv[]) {
@autoreleasepool {
int i = 3;
int(^myBlock)(int) = ^(int num){
j++;
num = num + j;
return num * i;
};
int res = myBlock(4);
printf("%d\n", res);
}
return 0;
}
通过代码实验,全局变量在代码块中无论是进行算术运算还是修改都不会出现报错现象,可见代码块对局部变量要仁慈的多。block的基础知识并不多,但是这些知识真的很重要,特别是在以后开发中,常会使用到的一种传值方式:block传值。没有这些block基础,到时候当然也就写不出来好的传值代码。