昨天使用一個小例子簡單說明了下Block作為參數時的使用。
今天再來復習一下Block作為返回值使用時的情況,先貼一小段熱門第三方框架Masonry的官方sample code:
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(superview).with.insets(padding);
}];
其中關於...equalTo(superview).....insets(padding)
之前沒接觸過這類用法的童鞋,可能看到這行代碼就瞬間一臉懵逼了(挖槽(⊙□⊙) ,點語法接括號參數再接點語法是什么鬼,我Object-C讀的少不要騙我...)。
淡定,還記得block的基本用法嗎block(參數)
,其實這里就是使用了Block用作了方法的返回值,同時在Block里面又返回了self自身而形成了一個鏈式結構。這樣說有些抽象,我們還是以昨天那個CalculatorManager工具類為例。
版本1.0
首先,我們先在工具類中實現一個很簡單的方法:外界傳遞一個整形參數,然后將其與原結果值相加,再保存起來作為新的結果值。
CalculatorManager.h文件
#import <Foundation/Foundation.h>
@interface CalculatorManager : NSObject
/** 結果值*/
@property(assign, nonatomic) int result;
-(void)add:(int)value;
@end
CalculatorManager.m文件
#import "CalculatorManager.h"
@implementation CalculatorManager
-(void)add:(int)value
{
_result += value;
}
@end
假設現在外部控制器調用該方法,需要計算得出從1加到4的結果值:
-(void)viewDidLoad {
[super viewDidLoad];
CalculatorManager *manager = [[CalculatorManager alloc] init];
[manager add: 1];
[manager add: 2];
[manager add: 3];
[manager add: 4];
NSLog(@"%d", manager.result);
}
代碼行數這么多,一股強烈的弱者氣息.....於是:
版本1.1:
修改(void)add:(int)方法,添加返回值,返回值為工具類self自身:
-(instancetype)add:(int)value
{
_result += value;
return self;
}
這樣外界控制器調用該方法時,就變成這樣了:
- (void)viewDidLoad {
[super viewDidLoad];
CalculatorManager *manager = [[CalculatorManager alloc] init];
[[[[manager add:1] add:2] add:3] add:4];
NSLog(@"%d", manager.result);
}
代碼變成了一行,比起之前清爽多了,但這長長的中括號[
嵌套看起來還是弱爆了,於是:
版本1.2
繼續修改(instancetype)add:(int)方法,將方法的返回值,替換為:一個返回值為CalculatorManager instance的Block代碼塊:
-(CalculatorManager *(^)(int))add
{
//方法本身返回一個blockd代碼塊
return ^CalculatorManager *(int value){
_result += value;
//block塊內部再返回一個instance實例
return self;
};
}
這樣外界就可以通過點語法這樣調用:
- (void)viewDidLoad {
[super viewDidLoad];
CalculatorManager *manager = [[CalculatorManager alloc] init];
manager.add(1).add(2).add(3).add(4);
NSLog(@"%d", manager.result);
}
瞬間逼格就提高了不少有木有(=゚ω゚)ノ。言歸正傳,據說這個叫鏈式編程思想,好處在於可以將多個方法,用點語法的方式鏈接起來,顯得簡潔、可讀性高。
如果先前對Block這類型的用法在理解上抱有疑惑的話,希望這個小例子能幫到您:)