block是在iOS 4.0之后出现的,封装了一段代码并将这段代码当做变量,通过block()的方式进行回调,说白了,就是把一个方法或者一些属性封装在一个box里面,然后再给box起个名字,想用这个方法或者属性的时候,就呼叫box的名字,然后自动调用里面的方法或者属性来使用.下面来说一下block的特点:
1.block的代码是内联的,效率和使用比较方便
2.block对外部变量默认是只读属性,封闭性比较强
下面先来认识一下block的构成,如下图(人家的图),block的=好的另一侧返回值是可以省略的,然后^符号衔接一个参数列表,使用括号包起来,告诉编译器这是一个block,然后使用大括号将block的代码封装起来.
对于希望在block中修改的外界局部变量,我们可以在这些变量上加上 __block关键字来修饰,__blcok的作用是把只读变量从栈上copy到堆上,等数据处理结束,再从堆上返回到栈上 ,这样就能在block中修改这些变量.比如:
int X = 10;
void (^printXAndY)(int) = ^(int y){
printf("%d %d\n",X,y);
};
printXAndY(345); print:10 345
在block块儿里面只能使用外部变量而不能修改外部变量,如果需要使用,用__block来修饰
__block int X = 10;
void (^printXAndY)(int) = ^(int y){
X = X + y;
printf("%d %d\n",X,y);
};
printXAndY(345);
下面来介绍一下block的应用
1.传值
a.首先声明一个block,注意要用copy来修饰
@property (nonatomic, copy)void (^changeColorBlock)(UIColor* currentColor);
b.给block内的参数赋值
UIColor *currentColor = [UIColor lightGrayColor];
_changeColorBlock(currentColor);
c.回调
NextViewController * nextVC= [[NextViewController alloc]init];
nextVC.changeColorBlock = ^(UIColor *currentColor) {
self.view.backgroundColor = currentColor;
};
[self presentViewController:nextVC animated:YES completion:nil];
2.调用方法
block名称后面的括号中不仅可以声明变量,也可以是方法,例如
__block NSInteger localCounter = 42;
__block char localCharacter;
void (^ablock)(void) = ^(void){
localCharacter = 'a';
++localCounter;
};
localCharacter = 'b';
ablock();
看一下输出
ablock()的调用执行了localCharacter = 'a';和++localCounter;,所以localCharacter = a,localCounter = 43.