Blocks是C语言的扩充功能:带有自动变量(局部变量)的匿名函数。通过Blocks,源代码中就能使用匿名函数,即不带名称的函数。在我们的工作中,命名占据了很大一部分,函数名,变量名,属性名,类名,框架名等都必须具备。能够编写不带名称的函数对程序员来说是具有相当吸引力的。
C语言中的函数:
返回值类型
函数名
(参数列表)
表达式
Blocks:^
返回值类型
(参数列表)
表达式
-
返回值类型
同OC/C语法中的返回值类型 -
参数列表
同C语法中的参数列表 -
表达式
同OC/C语法中允许使用的表达式
^int (int count) {return count++;}
^NSString * (NSNumber *num) {
return [NSString stringWithFormat:@%@",num"];
Blocks的省略句式
省略返回值
^
返回值类型 (参数列表)
表达式
^(int count) { return count++ }
^ (NSNumber *num) {
return [NSString stringWithFormat:@"%@",num];
}
省略返回值类型时,如果表达式中有return语句就使用该返回值类型,如果表达式中没有return语句就使用void
类型!
^(int count) {return count + 1;};
^(NSNumber *num) {
return [NSString stringWithFormat:@"%@",num];
}
^(NSNumber *count) {
NSLog(@"无返回值类型Block count = %@",count);
};
^(void) {
NSLog(@"无返回值类型也无参数Block");
};
Block类型的变量
在Block语法下, 可将 Block 语法赋值给声明为 Block 类型的变量中。 即源代码中一旦使用 Block 语法就相当于生成了可赋值给 Block 类型变量的 “值”。 Blocks 中由 Block语法生成的值也被称为 『Block』 。
声明Block类型变量的示例如下:
int (^counts) (int);
是不是和C语言的函数指针非常相似,区别就是将*
换成了^
,int (* counts) (int)
;
Block类型的变量和其他OC/C变量没有任何的区别
- 自动变量
- 函数参数
- 静态变量
- 静态全局变量
- 全局变量
int (^counts)(int) = ^(int count) {return count + 1;};
NSString *(^str) (NSNumber *num) = ^NSString *(NSNumber *num) {
return [NSString stringWithFormat:@"%@",num];
void (^blank) (NSNumber *count) = ^(NSNumber *count) {
NSLog(@"无返回类型Blok count = %@",count);
};
void (^blank)(void) = ^(void) {
NSLog(@"无返回值类型也无参数block");
};
在函数参数中使用Block类型变量向函数传递Block,即将Block
变量作为函数的形参:void func (int (^counts)(int)) { }
也可以使用typedef
来简化记述方式
typedef int (^count)(int);
void func(count num) { }
- (void)funcWithcount:(int (^)(int)) count { }
- (void)funcWithcount:(count) count { }
Block可以截获在它之前声明的变量,但也有特殊的地方,就是以const拷贝的方式访问非局部变量
int main(int argc,const char *argv[]) {
int val = 1;
void (^blk) = ^{pintf("val = %d\n",val);
val = 2;
blk();
return 0;
}
此时输出的val是1
;
如果要修改来自自动变量的值:__block
:
int main(int argc,const char *argv[]) {
__block int val = 1;
void (^blk) = ^{pintf("val = %d\n",val);
val = 2;
blk();
return 0;
}
此时输出的val
是2