Objective-C 語言一直以來由蘋果公司維護著,為其增加了不少更加現代化的語法,其中 block (其他語言一般都稱閉包)語法就是在 iOS 4 發布的,與此同時還提供了抽象程度極高的GCD 技術,用于簡化線程的操作!所以今天說的 block 并不是新的技術,但它恐怕是最難記憶的的語法了,并且使用形式很是靈活,因此總結一下我平時使用的幾種類型,供大家參考。
特為此寫了個 demo 來幫助理解。
1.描述為屬性
這是最為常見的用法了,一般都是先賦值,當觸發某個邏輯時進行回調;
@property (nonatomic, copy) returnType (^blockName)(parameterTypes);
self.blockName = ...;//賦值一個block
self.blcokName(parameters);//調用
2.作為形參(parameter),做回調
a.經常和屬性配合使用;一般場景是方法內部有異步執行的任務,執行完畢后通過這個block參數回調到調用處;
- (void)doSomeThingWithCompletion:(retunType (^)(parameterTypes))blockName{
async(...{
blockName(parameters);
});
}
b.相當于寫個 setter 方法,給 block 屬性賦值,直接給屬性賦值的話需要手寫實現 block ,不容易記,這其實是為了方便調用者而已。
- (void)registerXXXHandler:(void (^)(float))handler
{
self.xxxHandler = handler;
}
3.作為實參(argument),實現block
調用一個帶有 block 參數的方法時,就需要實現這個 block 了,其實這個不用手寫,IDE 會提示的,直接回車即可;
[self doSomeThingWithCompletion: ^retunType(parameters){
//...
}];
4. typedef 出"新類型"
以上使用一點也不友好,所以基本上我們都會使用 typedef 定義一個類型出來;
typedef returnType(^ TypeName)(parameterTypes)
//以上用法可改為:
@property (nonatomic, copy) TypeName blockName;
- (void)doSomeThingWithCompletion:(TypeName)blockName;
5.方法內部當局部變量使用
如果一段代碼里有很多個 if else 分支,某些分支的處理完全一樣時,可將他們封裝到一個block塊里面;可以省去寫相同代碼的麻煩,也不必開辟一個新的方法;
returnType (^blcokNmae)(parameterTypes) = ^returnType(parameters){ ... };
//調用:
returnType result = blcokNmae(parameters);
6.方法返回值
這種情況不太多,比如可用于實現鏈式編程;
//聲明
- (returnType (^) parameterTypes) method;
//實現
- (returnType (^) parameterTypes) method{
return ^ returnType (parameters){
//...
return obj;//obj 是 returnType 類型
};
}
舉個例子:
///設置url
- (SLNetworkRequest *(^)(NSString *url))c_URL;
- (SLNetworkRequest *(^)(NSString *url))c_URL
{
return ^ SLNetworkRequest * (NSString *url){
self.urlString = url;
return self;
};
}
7.高階 Block : 作為另一個Block的參數
這種情況用的不是太多,但是一旦有需要雙向交互的場景時,優勢就很明顯了!具體可看 demo 實現的 3G 網絡詢問用戶是否下載的場景:
typedef returnType(^ Block1)(parameterTypes)
typedef returnType(^ Block2)(parameterTypes, Block1) //Block1作為Block2的參數部分
可實現雙向通信,比如:
- (void)doSomeThingWithCompletion:(Block2)blockName
{
async(...{
Block1 block1 = ^(isOk){
if(isOK){
//start download...
}else{
//cancel something...
}
};
blockName(parameters, block1);
});
}
調用:
[self doSomeThingWithCompletion: ^ returnType(parameters, block1){
//內部處理完畢后,回調到此;
//根據結果(parameters)做相應的邏輯,然后將處理結果再次回調到方法內部
if(parameters){
block1(NO);//通過block1再次回調回去告知可以進行下一步了
}else{
block1(YES);//通過block1再次回調回去告知不能繼續
}
}];
最近我制定了 H5-Native 的交互方案,編寫交互需要注入的 js 腳本,通信 API 也是雙向的,其原理就是 block (閉包)的嵌套使用;API 出來后 H5 和 Native 的開發同事們都很 Happy 呢!
如果你有其他有趣的使用方法,請提供給我吧!
前五個算是翻譯,不過也確實是工作中經常用的,原文地址 : http://fuckingblocksyntax.com