block常用的场景:
- 当做属性传值
- 当做方法的参数回调
- 当做方法的返回值使用
前面2种比较常见,也比较容易使用,第3种很少见,运用的比较高深,可以将代码发展成链式编程。后面详细讲解下第3种用法以及它是如何实现的。
1、正常定义一个方法如下所示
- (void)blockTest {
NSLog(@"blockTest");
}
在viewDidLoad方法中直接调用
self.blockTest;
运行结果:
运行结果.png
2、将blockTest这个方法的返回值变成一个block,如下所示
- (void(^)())blockTest {
void(^block)() = ^{
NSLog(@"blockTest");
};
return block;
}
// 上面还可以简写成以下方式,代码是一模一样的,只是少了定义block
- (void(^)())blockTest {
return ^{
NSLog(@"blockTest");
};
}
然后在viewDidLoad中调用时就变成了如下
// 在方法后面多了一个()
self.blockTest()
// 上面的写法就等于直接调用了一个block
^{
NSLog(@"blockTest");
}()
// 更好的理解写法请看下面
void(^blockTest)() = ^{
NSLog(@"blockTest");
};
blockTest();
运行结果和步骤1的一样。
以上展现的一个思想就是将block分装成了方法的返回值来使用,你调用的是一个方法,实际就是定义一个block并马上调用这个block。
3、接下来我们给这个block添加一个参数
- (void(^)(NSString *))blockTest {
return ^(NSString *name){
NSLog(@"blockTest --> %@",name);
};
}
在viewDidLoad中调用变成了
// 括号内多了需要传递的参数
self.blockTest(@"doudou");
现在可以通过block传递参数了
4、终极变形,链式编程
给block添加一个返回值,代码变成了如下形式
// 因为返回值是当前的类,所以在block代码里需要return self
- (ViewController *(^)(NSString *))blockTest {
return ^(NSString *name){
NSLog(@"blockTest --> %@",name);
return self;
};
}
参照上面的方法,然后再自定义一个方法yourName,如下
- (ViewController *(^)(NSString *))yourName {
return ^(NSString *name){
NSLog(@"yourName --> %@",name);
return self;
};
}
在viewDidLoad中进行调用
// 可以通过一个点(.)不断的调用方法
self.blockTest(@"doudou").yourName(@"yiliu");
运行结果如下
运行结果.png
以上就是将block当做返回值的一个运行过程。