代码块本质上是和其他变量类似。不同的是,代码块存储的数据是一个函数体。
Block代码块和C语言中的函数指针类似,Objective-C中的SEL也与函数指针类似。函数指针用来保存一个C函数的地址,SEL用来保存一个成员函数的地址,而Block则用来保存一个代码块的地址。使用代码块时,你可以像调用其他标准函数一样,传入参数,并得到返回值。脱字符(^)是块的语法标记。
创建一个简单的block
代码:
1 | // 定义了一个无参数,返回类型为void的printBlock的变量。 |
运行结果:
1 | 2016-05-19 15:59:59.157 blogTestCode[15443:285677] hello world! |
创建多参数的block
代码:
1 | int (^calculateNum)(int x, int y); |
运行结果:
1 | 2016-05-19 15:48:30.843 blogTestCode[15415:275933] 3 |
创建参数为OC对象的block
代码:
1 | // 定义变量的时候直接初始化 |
运行结果:
1 | 2016-05-19 16:06:02.437 blogTestCode[15478:290573] hello block |
调用系统的代码块进行数组排序
代码:
1 | NSArray *stringArray = [NSArray arrayWithObjects:@"abc 2", @"abc 5", @"abc 1",@"abc 4",@"abc 3",nil]; |
运行结果:
1 | 2016-05-19 16:16:12.683 blogTestCode[15499:296615] ( |
自定义Block类型
代码:
1 | // 首先在文件最上方定义Block类型 |
运行结果:
1 | 2016-05-19 16:34:51.499 blogTestCode[15617:310741] ( |
常见错误
在代码块中使用局部变量
代码:
1 | // 局部变量 |
运行结果:
1 | 2016-05-19 16:43:34.237 blogTestCode[15694:318406] 5 |
在代码块中使用全局变量
代码:
1 | // 全局变量 |
运行结果:
1 | 2016-05-19 16:43:34.237 blogTestCode[15694:318406] 10 |
在代码块中改变局部变量
代码:
1 | // 局部变量需要加__block前缀,否则会报错。而且block中的num是自己定义的num,可以在代码块中改变num的值。 |
运行结果:
1 | 2016-05-19 16:59:29.609 blogTestCode[15748:330854] B:5 |
在代码块中改变全局变量
代码:
1 | // 全局变量不需要加block修饰,而且block中的num是自己定义的num,可以在代码块中改变num的值。 |
运行结果:
1 | 2016-05-19 17:07:55.873 blogTestCode[15763:336709] B:5 |
代码块的递归调用
代码块想要递归调用,代码块变量必须是全局变量或者是静态变量,这样在程序启动的时候代码块变量就初始化了,从而才能进行递归调用。