1、基本概念
block是代码段,是一段允许执行的代码,可以理解为是一种特殊的对象。有些编程语言将其称之为闭包(closure),是iOS4之后新增的语法。
在OC中block可以定义为属性,方法参数,临时变量等
2、常用形式
//无参无返回值
void(^theBlock1)() = ^(){
};
//有参无返回值
void(^theBlock2)(int,int) = ^(int a,int b){
};
//无参有返回值
int(^theBlock3)() = ^(){
return 0;
};
//有参有返回值
int(^theBlock4)(int,int) = ^(int a,int b){
return a+b;
};
3、使用typedef定义
typedef int (^MyBlock)(int,int);
int main(int argc, const char * argv[]) {
@autoreleasepool {
MyBlock theBlock = ^(int a,int b){
return a+b;
};
NSLog(@"%d",theBlock(1,1));
}
return 0;
}
4、定义成方法参数
- (void)callDemo:(void(^)(NSString * str))theBlock
{
//接收到外界传入的block,在这个方法里面调用一下
theBlock(@“AA");
}
5、定义成属性
typedef void(^MyBlock)(int,int);
@interface ViewController ()
@property (nonatomic,assign) int num;
/// block定义成属性
@property (nonatomic,copy) void (^theBlock1)();
@property (nonatomic,copy) MyBlock theBlock2;
@end
6、block访问和修改外部的变量
默认在block内是不允许修改外部变量的,如果想修改必须用__block来标示变量,让编译器知道这个变量是在block内部做修改操作的。
在ARC的环境中block访问和修改外部变量
- 单纯的定义一个block,那么block存放在全局区
- block访问外部变量的时候,外部变量在内存中存储区域的变化:
- 访问前变量存放在栈区,访问时变量存放在栈区,访问后变量存放在栈区
- block修改外部变量的时候,外部变量在内存中存储区域的变化:
- 修改前变量存放在栈区(被__block修饰后存储位置不受影响),修改时变量存放在堆区,修改后变量存放在堆区
7、block在OC中定义为属性要用copy修饰
在MRC的环境中,block存放在栈区,不能全局共享,要想实现全局共享要把其copy到堆区,这是原因所在,那么在ARC环境中strong和copy效果是一样的,但是苹果官方推荐还是用copy修饰