1.block的声明
返回值类型(^block的名字)(参数类型);
- 无参无返回值的block
void(^block1)();
- 有参无返回值的block
void(^block2)(int);
- 无参有返回值的block
int(^block3)();
- 有参有返回值的block
int(^block4)(int, int);
记不住block的语法怎么办?
直接敲inlineBlock会有提示,或者上这个网站http://fuckingblocksyntax.com
2.block的赋值
返回值类型(^block的名字)(参数类型) = ^(参数类型 参数){
代码
}
- 无参无返回值的block
void(^block1)() = ^() {
NSLog(@"");
};
- 有参无返回值的block
void(^block2)(int) = ^(int a) {
NSLog(@"a");
};
- 无参有返回值的block
int(^block3)() = ^() {
return 22;
};
- 有参有返回值的block
int(^block4)(int, int) = ^(int a, int b) {
return a + b;
};
3.block的调用
- 无参无返回值的block的调用
block1();
- 有参无返回值的block的调用
block2(2);
- 无参有返回值的block的调用
int c = block3();
- 有参有返回值的block的调用
int d = block4(1, 2);
4.block作为属性使用
@property(nonatomic,copy)返回值类型(^block的名字)(参数类型);
@property(nonatomic,copy)void(^myBlock)();
或者可以给block起一个别名
typedef void(^Block)();
@property(nonatomic,copy)Block block;
4.block作为代理使用(传值和调用其他类中的方法)
代理同样可以实现这两种功能,block在这种使用情况下可以和代理做一个类比.
代理使用的时候代理者和被代理者都需要实现三个步骤:
被代理者
- 定义一个协议
- 拥有代理属性
- 在合适的时候调用代理方法
代理者
- 遵守代理协议
- 将代理设置给自己
- 实现代理方法
block:
被代理者
- 声明一个block属性
- 在合适的时候调用block
代理者:
- 给block赋值
代码实现:
控制器A跳转到控制器B,实现在控制器B中调用控制器A中的方法并且传一个值给控制器A
控制器B中的代码:
@property(nonatomic,copy)void(^myBlock)(int a);
//按钮点击方法
- (IBAction)transmit:(id)sender {
if (self.myBlock != nil) {
self.myBlock(2);
}
}
控制器A中的代码:
newVC.myBlock = ^(int a) {
NSLog(@"%d", a);
//调用控制器A中的方法
[self functionOfControllerA];
};
跟代理一样,传值是通过参数实现的.不需要传值的话就不用写参数.
5.作为函数参数使用
作为函数的参数使用的时候多数是用来回调.
以下载图片为例:
//下载图片的方法
- (void)downloadImgSuccess: (void(^)(UIImage *img))successBlock failure: (void(^)())failureBlock {
//在这里写下载图片的代码
if (下载失败) {
//下载失败的回调方法
failureBlock();
} else {
//下载成功 将图片回调回去
successBlock(img);
}
}
//调用下载图片方法
[self downloadImgSuccess:^(UIImage *img) {
//下载成功后执行的代码
weakSelf.imageView = img;
NSLog(@"成功");
} failure:^{
//下载失败后执行的代码
NSLog(@"失败");
}];
6.block为什么要使用copy关键字修饰??
在MRC环境下:
block没有引用外部局部变量,block存储在全局区.
block引用了外部局部变量,block存储在栈区
在ARC环境下:
block没有引用外部局部变量,block存储在全局区
block引用了外部局部变量,block存储在堆区
局部变量是存储在栈区的,栈区中的变量超出作用域后会被回收,所以需要使用copy关键字将局部变量拷贝一份到堆区,防止block因为访问已经回收的局部变量发生野指针错误.
注意:在block中使用self关键字的时候注意将self处理成弱引用以免发生循环引用
__weak typeof(self) weakSelf = self;