Block即块,在OC中可以使用它来封装代码,在运行中保存代码,而且Block可以作为函数参数或者函数的返回值,而本身也可以带参数和返回值。block在多线程,异步,集合遍历,动画等场景被广泛使用。
先看一段代码,摘自苹果官方的文档
int multiplier = 7;
int (^myBlock)(int) = ^(int num) {
return num * multiplier;
};
从中可以很容易了解到一个Block的结构以及如何定义一个Block。
- Block的标志位 ^
- Block的名称为 myBlock
- Block的参数为一个int,且名称为num
- Block的返回值为一个int
- Block的主体为{ return num * multiplier; }
调用上面的Block使用
NSLog(@"%d", myBlock(3));
运行结果:
Block可以访问外部的变量,这一点函数是做不到的。
如上图所示,如果在Block内想要修改直接外部的局部变量是不被允许的,但是根据错误提示,可以在d前加上__block类型修饰符,即可在Block内进行修改。
// main.m
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
@autoreleasepool {
__block int d = 0;
// 计算一点到坐标原点的距离
double (^distance)(double , double) = ^(double x, double y){
d = pow(x, 2) + pow(y, 2);
return pow(x, 2) + pow(y, 2);
};
NSLog(@"坐标(5,4),距原点 = %lf",distance(5,4));
}
return 0;
}
运行结果为:
可以使用typedef为Block定义别名,比如上面的程序可以改写成:
// main.m
#import <Foundation/Foundation.h>
typedef double(^Distance)(double,double);
int main(int argc, const char * argv[])
{
@autoreleasepool {
__block int d = 0;
// 计算一点到坐标原点的距离
Distance distance = ^(double x, double y){
d = pow(x, 2) + pow(y, 2);
return pow(x, 2) + pow(y, 2);
};
NSLog(@"坐标(5,4),距原点 = %lf",distance(5,4));
}
return 0;
}