导读:
- 一、Block是什么
- 二、Block的特点和作用
- 三、Block的声明、定义及注意事项
- 四、如何使用Block
- 五、使用Block的注意事项
一、Block是什么
- Block的本质是一段能被执行的代码块
- Block是一个普通的Objective-C对象
- Block是对闭包的实现,即Objective-C语言中的闭包
二、Block的特点和作用
- block使代码更简洁紧凑,易于阅读
- 比函数使用更方便、更美观
- 能够在将来(一段时间后)被执行
- Block可以作返回值、形参、属性、给变量赋值
三、Block的声明和定义
-
苹果官方的Block例子
- Block的声明
//Block的声明格式
return_type (^block_name) (param_type, param_type, ...)
//Block声明的例子
int (^add) (int, int)
- Block的定义
Block的定义格式
^return_type (param_type param_name, param_type param_name, ...) { ... return return_type; }
Block定义的例子
^(int number1, int number2) { return number1 + number2; }
- Block的声明和定义可以写在一起
int (^add) (int, int) = ^(int number1, int number2) { return number1 + number2; }
//调用block
int result = add(1,2);
- Block声明、定义时的注意事项
(1) 声明时,返回类型可以是空,空时为void,返回基本数据时如上,返回非基本数据类型时加*,如(NSString **)
(2) 声明时,可以无参数;有参数时要指明参数类型,可以无参数名
(3) 定义时,返回类型为空时可以省略,不为空时不能省略
(4) 定义时,参数为空时圆括号可不写,有参数时要指明参数的类型和参数名称
四、如何使用Block
- block的调用和参数赋值在函数内部,block的定义在调用函数时。
- Block作参数
//声明一个接收block作为参数的方法
- (void)doMathWithBlock:(NSString *(^)(NSString *, NSString *))mathBlock{
//block调用部分
NSLog(@"label text is %@",mathBlock(@"hello",@"world"));
}
- (void)buttonTapped {
//block实现部分
[self doMathWithBlock:^(NSString *firstStr, NSString *secondStr) {
return [NSString stringWithFormat:@"%@--%@",firstStr,secondStr];
}];
}
[self buttonTapped];
//调用结果是:label text is hello--world
- Block作属性,这种方式在处理异步任务的时候特别有用,在一个异步任务完成之后存储一个block,之后可以调用。下面是一段示例代码
@interface MTViewController ()
@property (copy) NSString *(^mathstoreBlock)(NSString *, NSString *);
@end
//存储block并存储其实现过程
- (void)doMathWithBlock:(NSString *(^)(NSString *, NSString *))mathBlock{
self.mathstoreBlock = mathBlock;
}
//block实现部分
- (void)buttonTapped {
[self doMathWithBlock:^(NSString *firstStr, NSString *secondStr) {
return [NSString stringWithFormat:@"%@--%@",firstStr,secondStr];
}];
}
//调用存储的mathstoreBlock
- (void)invokeStoreBlock {
NSLog(@"label text is %@",self.mathstoreBlock(@"hello",@"world"));
}
[self buttonTapped];
[self invokeStoreBlock];
//调用结果是:label text is hello--world
- 使用typedef来简化block语法
typedef NSString *(^MathstoreBlock)(NSString *, NSString *);
@interface MTViewController ()
@property (copy) MathstoreBlock mathstoreBlock;
@end
其他使用和2一样
五、使用Block的注意事项
- block中可以访问全局变量,并可以给全局变量赋值
- block中可以访问局部变量,但不能给局部变量赋值
- 如果想给block中的局部变量赋值,则需要在局部变量前加__block关键字
- block中使用self时需要弱化
__weak typeof(self) weakself = self;
- block作属性时用copy