先看两个实例
1、
typedef void(^captureObjectBlock)(void);
captureObjectBlock testBlock;
- (void)viewDidLoad {
[super viewDidLoad];
[self captureObject];
testBlock();
}
- (void)captureObject {
int captureNum = 1;
testBlock = ^() {
NSLog(@"num = %d", captureNum);
};
captureNum = 2;
}
上面打印的是几?captureNum 出作用域之后是否别销毁?
打印结果:
num = 1
同样类型的实例
typedef void(^captureObjectBlock2)(NSObject *);
captureObjectBlock2 testBlock2;
- (void)viewDidLoad {
[super viewDidLoad];
[self captureObject2];
testBlock2([[NSObject alloc] init]);
testBlock2([[NSObject alloc] init]);
testBlock2([[NSObject alloc] init]);
}
- (void)captureObject2 {
NSMutableArray *mutArray = [[NSMutableArray alloc] init];
testBlock2 = ^(NSObject *obj) {
[mutArray addObject:obj];
NSLog(@"mutArray元素的个数:%ld", [mutArray count]);
};
}
打印的数组的个数是多少?
有人会回答:mutArray是captureObject方法的局部变量,mutArray指针 保存到栈上,那么当执行完captureObject方法后,出去了作用域mutArray变量就会被系统自动释放。
所以当执行captureBlk([[NSObject alloc] init]); 的时候,mutArray为nil,每次打印的为0。
这是错误的,实际为
mutArray元素的个数:1
mutArray元素的个数:2
mutArray元素的个数:3
那么如果把上面代码中的mutArray改为weak类型:
NSMutableArray __weak *mutArray = [[NSMutableArray alloc] init];
打印结果:
mutArray元素的个数:0
mutArray元素的个数:0
mutArray元素的个数:0
2、
__block int testNum = 10;
void (^block)(void) = ^() {
NSLog(@"读取局部变量:%d", testNum);
testNum = 1000;
};
testNum = 20;
block();
NSLog(@"block执行后的值:%d", testNum);
打印结果:
读取局部变量:20
block执行后的值:1000
本文会分析上面的代码中block底层 都做了哪些操作。
用过block的可以 直接忽略前面的语法部分。直接从第三部分看即可。
一、block的使用
1、block声明
void (^blockName)(int arg1, int arg2);
中文翻译:返回值(^block变量名)(block的参数)
参数名称可以省略,也可以写成:
void (^blockName)(int, int);
2、block定义
^void(int arg1, int arg2) {
};
中文翻译:^返回类型(block的参数)
返回类型可以省略,也可以写成:
^(int arg1, int arg2) {};
声明定义和调用:
void (^blockName)(int, int) = ^(int arg1, int arg2) {
NSLog(@"arg1 + arg2 = %d", arg1 + arg2);
};
blockName(1,2);
block作为方法的参数:
- (void)viewDidLoad {
//2、没有参数
void (^blockName2)() = ^() {
NSLog(@"block2");
};
blockName2();
//3、block有返回值
int (^blockName3)(int) = ^(int n) {
return n * 2;
};
//4、block作为方法的参数
[self testBlock2:blockName3];
}
- (void)testBlock2:(int(^)(int))myBlock {
myBlock(10);
}
3、block只有在调用的时候才会执行里面的函数内容。
二、block调用外部变量
1、全局变量,block可以进行读取和修改。
@interface ViewController () {
NSInteger num;
}