前面簡單的說了Block可以作為屬性属瓣,方法參數(shù)和方法返回使用讯柔。這里更加詳細(xì)的介紹一下Block魂迄,并且結(jié)合實際情況對Block進(jìn)行使用。
-
什么是Block
Block又稱作是閉包极祸、塊遥金。這兩種概念又是什么呢蒜田?
Block是一種函數(shù),這種函數(shù)在別的函數(shù)內(nèi)部存在美莫,并且可以使用其所在函數(shù)內(nèi)的局部變量梯捕。
希望這樣的解釋稍微容易理解一些。
-
Block的寫法和調(diào)用
在xcode里面襟铭,可以輸入inlineBlock獲取Block的基本寫法:
returnType(^blockName)(parameterTypes) = ^(parameters) {
statements
};
調(diào)用的時候寒砖,直接使用名字加一對小括號就可以了:
blockName ();
但是這個地方有一個坑,它省略了等號后面的返回類型哩都。一般情況下沒有什么問題漠嵌,但是如果返回的是nil咐汞,編譯器就會報錯。如下圖:
我們只要在等號后面加上對應(yīng)的返回值献雅,即可編譯通過碉考。
所以嚴(yán)格意義上,等號后面也應(yīng)該有返回類型挺身。
-
Block在實際開發(fā)中的使用
我們先定義一個類侯谁,叫Person。
1. block作為屬性
給我們之前定義的person類增加一個屬性:
//對Block的修飾:MRC用copy章钾,ARC用Strong
@property (nonatomic, strong) void(^eat)(void);
然后測試一下:
Person *p = [Person new];
//Block作為屬性
p.eat = ^{
NSLog(@"吃飯了墙贱!");
};
_p = p;
調(diào)用:
_p.eat();
控制臺輸出:
吃飯了
2. block作為方法參數(shù)
還是給之前的Person類增加一個新的方法:
.h
//Block作為參數(shù)時贱傀,blockname不需要寫在^后面惨撇,直接寫在括號后面
- (void)eatWith:(void(^)(void))block;
.m
- (void)eatWith:(void (^)(void))block {
block();
}
測試代碼:
//Block作為方法參數(shù)
[_p eatWith:^{
NSLog(@"吃了一頓大餐!");
}];
控制臺輸出:
吃了一頓大餐
3. block作為方法的返回值
.h
//Block作為返回值
- (void(^)(int i))run;
.m
- (void(^)(int i))run {
return ^(int i){
NSLog(@"我走了%d米",i);
};
}
測試調(diào)用:
void(^block)(int i)= _p.run;
block(1);
//上面這兩行代碼可以合并為下面這一行
_p.run(1);//有沒有發(fā)現(xiàn)這個調(diào)用和block作為屬性時是一樣的府寒,下面會繼續(xù)分析
控制臺輸出:
我走了1米
-
關(guān)于Block用法的引申思考
在前面魁衙,我們簡單的運(yùn)用了block的幾種使用場景,但是在使用過程中株搔,逐漸體會到了block的神奇剖淀。
1. 函數(shù)式編程
把Block當(dāng)做函數(shù)的參數(shù),可以把我們的邏輯和函數(shù)放在調(diào)用時候的block里面纤房,而不是方法內(nèi)部纵隔。這樣會讓我們在寫代碼的時候,把相關(guān)的邏輯都放在一起炮姨,提高了開發(fā)效率和程序的可讀性捌刮。這其實就是函數(shù)式編程思想清女。函數(shù)式編程在很多第三方框架中都有明顯的體現(xiàn)与境,比如說我們頻繁使用的AFNetWorking、Masonry等骤竹。
我們這里對Masonry框架進(jìn)行一些簡單的分析蛾派。
Masonry是一個輕量級的布局框架棚蓄。這是一個非常簡單并且常見的Masonry框架的運(yùn)用:
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(superview).with.insets(padding);
}];
2.鏈?zhǔn)秸{(diào)用
外面的block就是一個函數(shù)式編程的體現(xiàn)堕扶,但是我們看到它在Block內(nèi)部調(diào)用方法的時候,不是像我們使用常規(guī)的OC語言一樣梭依,而是不斷地使用點語法調(diào)用稍算,極大的精簡了代碼量,同時也擁有很好的可讀性役拴,使用起來極其方便糊探。這種方式叫鏈?zhǔn)秸{(diào)用。
那么結(jié)合我們剛剛對block的使用河闰,鏈?zhǔn)秸{(diào)用時怎么實現(xiàn)的呢科平?
- 后面帶括號,說明方法的返回值是一個Block姜性。
- 調(diào)用方法肯定是對象才可以進(jìn)行調(diào)用瞪慧,說明Block的返回值是一個對象。
- 點語法則說明這個方法沒有參數(shù)部念。
結(jié)合以上三點思考弃酌,我們可以得出一個結(jié)論,一個沒有參數(shù)&有返回值&返回值是Block&Block的返回值是方法的調(diào)用者的方法儡炼,就可以實現(xiàn)鏈?zhǔn)秸{(diào)用:
.h
//鏈?zhǔn)秸{(diào)用方法
- (Person *(^)(NSString *city))travel;
.m
- (Person *(^)(NSString *))travel {
return ^(NSString *city){
NSLog(@"我去了%@",city);
return self;
};
}
測試一下:
//鏈?zhǔn)秸{(diào)用
_p.travel(@"重慶").travel(@"北京");
控制臺輸出:
我去了重慶
我去了北京
這樣我們就實現(xiàn)了鏈?zhǔn)秸{(diào)用妓湘。
函數(shù)式編程和鏈?zhǔn)秸{(diào)用就是Masonry用到的主要思想。我用這兩種思想乌询,寫了一個簡單的計算器榜贴。可以通過鏈?zhǔn)秸{(diào)用的方式做運(yùn)算妹田,代碼和之前的demo都放在git上點擊前往唬党。