什么是block?######
block是C语言的扩充功能,可以用一句话来表示C语言的扩中功能,带有自变量(局部变量的)匿名函数。
匿名函数就是不带名称的函数。C语言的标准函数不允许有这样的函数。例如:
int func(int count);
它是声明了一个名字为func的函数,下面的源代码中调用了这个函数,必须使用该函数的名称func。
代用这个函数的时候,必须使用这个函数的名称。
int result = func(10);
使用函数指针,也仍然需要知道函数的名称,在赋值给函数指针时,若不使用想赋值的函数名称,就无法取得该函数的地址。
int (* funcprt) (int) = &func;
int result = (*funcprt) (10);
通过block就能使用匿名函数,即不需要函数名称的函数。
这里我们就知道了带有自动变量的匿名函数,中的匿名函数的概念。
下面解释一下自动变量:
C语言中的函数可能使用的变量有(自动变量,函数的参数,静态变量)
block的模式######
讲解一下带有自动变量值得匿名函数block的语法,即block表达式语法。
^(int event){
printf("1234567");
}
block的完整方式如下:
^ void(int event){
printf("123456");
}
完整方式与C语言的函数相比,仅有两点不同
(1)没有函数名称
(2)多了一个^
^代表block的插入号
^ 返回值类型 参数列表 表达式
例如可以写如下的block语法:
^ int(int count){
return count + 1;
}
如果不使用参数,参数列表也可以省略
^ (void){NSLog(@"1");}
^{NSLog(@"2");} //block可以省略返回值和参数类型
block类型变量######
block的语法从记述方式上来讲,除了有两点不同之外,其他方面跟C语言的记述方式相同。不同处在于多了一个插入符号^,缺少了一个函数名。
int func(int count){
return count + 1;
}
int (* funcptr) (int) = &func;
在block中,可以将block语法赋值给声明的block类型的变量中。
声明block变量类型,如下声明方式:
int (^block)(int);
与前面使用函数指针的源代码相比,声明一个block的变量类型,只是把*换成了^。该变量与C语言的变量类型完全相同。
下面是用block语法,把block赋值给block的变量类型。
int (^block) (int) = ^ (int count){
return count + 1;
}
有^生成的block语法赋值给了block,因此与通常的变量相同,当然也可以用block类型变量向block类型变量赋值。
int (^block1)(int) =block;
int (^block2)(int);
block2 = block1;
在函数中使用block变量类型,可以向函数中传递block参数。
- (void)func:(int (^blc)(int));
在函数中指定block类型,可以将block作为函数的返回值返回
函数参数和返回值中使用block类型变量的时候,记述方式很复杂,这时,我们可以用typedef来解决这个问题。
typedef int (^blc_t)(int);
通过使用typedef声明blc_t类型
void func(int (^blk)(int))
void func(blc_t blk){
}
通过typedef函数变得更容易理解,当然在oc中也可以这样是使用:
typedef int (^blk_t)(int);//定义一个blk_t的变量类型
blk_t blk = ^(int count){
return count +1;
}
- (int) mehtodUsingBlock:(blk_t )blk rate:(int)rate{
return blk(rate);
}
截获自动变量值######
通过block语法和block变量类型,我们已经理解的了带有自动变量的匿名函数中的匿名函数,现在需要理解一下什么是自动变量。
int main(){
int dmy = 256;
int val = 10;
const char * fmt = "val = %d\n";
void (^blk) (void) = ^{
printf("fmt,val");
};
blc();
return 0;
}
block的语法表达式,使用的是它之前声明的自动变量fmt和val。在block中,block表达式截获的是自动变量的值,即保存自动变量的瞬间值。因为block表达式保存了自动变量的值,所有,在执行block语法后,即使改写block中的自动变量的值,也不会影响block执行时,自动变量的值,所以在执行block语法后,即使改写block中自动变量的值,也不会影响block执行时,自动变量的值。该源代码在block语法后,改写了block中的自动变量的值val和fmt。
__block说明符######
实际上自动变量值截获,执行blokc语法只能保存其瞬间值。保存后就不能改写该值。
尝试改写截获的自动变量值,需要在自动变量上加上__block来修饰自动变量值。
__block int val = 0;
void (^blk)(void) = ^{
val = val +1;
}
blk();
printf("val = %d\n",val)
截获的自动变量######
如果截获的是oc对象,下面的代码是没有问题的。
id array = [NSMutableArray alloc]init];
void (^blk)(void) = ^{
id objc =[ [NSObject alloc]init];
[array addobject objc];
};
这个是没有问题的,而想array 直接赋值就会产生错误。
id array =[ [NSMutableArray alloc]init];
void (^blk)(void) = ^{
array = [[NSMutableArray alloc]init];
};
正确的应该是:
__block id array = [[NSMutableArray alloc]init];
void (^blk)(void){
array = [[NSMutableArray alloc]init];
};
blocks的实现#####
block的实质######
Block是带有自变量值的匿名函数。
网友评论