block 在Objective-C 中使用的频率还是非常高的,网上关于介绍block 的文章也非常多,本文旨在用最少、最浅显的语言介绍block。
block 是什么?
block 在OC 中就是一个对象,但他的值是一段代码,并且有返回值和入参。
// 声明数组
NSArray *array = @[@"a", @"b"];
// 声明block
NSInteger (^sumNumbersBlock)(NSInteger a, NSInteger b) = ^(NSInteger a, NSInteger b) {
return a+b;
};
从表面上看,声明数组和block 还是有很大不同的,但还是有一些相同点:
等号左边命名部分:
NSInteger (^sumNumbersBlock)(NSInteger a, NSInteger b);
- 返回值:block 需要指定返回值,上面的代码中返回值类型为
NSInteger
,如果什么都不返回,使用void
就可以了 - 类型+变量名称:格式为:
(^blockName)
,其中^
表示对象类型为block,并用()
将^
和对象名称包起来。 - 参数:如果参数为空,使用
()
,若不为空,像这样写(NSInteger a, NSInteger b)
。
等号右边赋值部分:
三部分:^
+ ( 参数 )
+ { block 实现的逻辑代码 }
void (^block)(NSInteger a, NSInteger b);
block = ^(NSInteger a, NSInteger b) {
// your code
};
block 应该注意的细节:
- 局部变量:block 中修改局部变量时需要使用__block 修饰符,否则只能获取但不能修改。
- 全局变量:block 中可以直接获取并且修改,不需要任何修饰符。
- 循环引用:block 中的对象变量需要使用__weak 修饰符,防止循环引用导致内存泄露。
- block 中的变量(除对象变量)在block 代码块之后发生变化,该变量在block 中也不会发生变化。
block 应用场景
- 回调:block 作为属性时,可以直接将回调的代码对block 进行赋值,相比delegate,结构更加简单,代码预读起来也更加方便。
- 入参:block 可以作为方法的入参使用,可以有效的分离业务模块和功能模块,降低代码的耦合。
- OC 链式编程:OC 中使用链式编程可以使用block 实现。