看到一個網(wǎng)站http://fuckingblocksyntax.com/ 簡單總結(jié)了Block的語法。
網(wǎng)站名很有意思,大概就是我操你大爺?shù)腂lock語法,網(wǎng)站作者取如此“高雅”的名字,也從側(cè)面反應(yīng)了Block語法的繁瑣。
網(wǎng)站截圖

其實(shí)Block的語法還是有跡可循的,順著網(wǎng)站的內(nèi)容,順便也整理一下我的Block筆記。
以下是我的理解和筆記,為了方便講解,我并不會按照上面的順序講述
一.作為一個局部變量
As a local variable:
returnType (^blockName)(parameterTypes) = ^returnType(parameters) {...};
// 聲明一個無參的名字為sayHello的block
void (^sayHello)() = ^void(){
NSLog(@"hello");
};
// 聲明一個參數(shù)為NString,名字為sayHelloAndName的block
void (^sayHelloAndName)(NSString *) = ^void(NSString *name){
NSLog(@"hello,%@",name);
};
int main(int argc, const char * argv[]) {
@autoreleasepool {
sayHello(); // hello
sayHelloAndName(@"chenbingua"); // hello,chenbinghua
}
return 0;
}
Xcode也考慮到很多人會偶爾忘記怎么寫一個Block,所以在Xcode輸入 'inlineBlock'或前幾個字母的時(shí)候,會輸出一下代碼
剛開始學(xué)習(xí)Block的時(shí)候,常常會忘記怎么寫。后來想到一個竅門,先回想一下c語言的函數(shù)或者java的方法。
例如c語言的函數(shù)是這樣寫的
// 函數(shù)的聲明
int sum(int,int);
// 函數(shù)的定義
int sum(int a,int b){
return a + b;
}
從C語言函數(shù)的聲明稍微變化一下就變成Block int (^sum)(int,int)
這里值得注意的是,Block不能通過傳進(jìn)不同參數(shù)實(shí)現(xiàn)類似Java的方法重載,要是硬要把一個NSString傳進(jìn)sayHello的block,例如調(diào)用sayHello(@"chenbinghua"),執(zhí)行結(jié)果依然是打印hello,即只是調(diào)用了sayHello()。為什么這樣呢,還要研究研究。
二.作為一個typeof
As a typedef:
typedef returnType (^TypeName)(parameterTypes);
TypeName blockName = ^returnType(parameters) {...};
block也可以先定義類型后實(shí)現(xiàn)
// 定義一個無參的,類型名為SayHello的block
typedef void (^SayHello)();
// 利用SayHello類型的block聲明一個sayHello變量,并實(shí)現(xiàn)
SayHello sayHello = ^(){
NSLog(@"hello");
};
int main(int argc, const char * argv[]) {
@autoreleasepool {
sayHello(); //hello
}
return 0;
}
三.作為一個類成員屬性
As a property:
@property (nonatomic, copy) returnType (^blockName)(parameterTypes);
@property關(guān)鍵字的參數(shù)要用copy,這關(guān)乎block的內(nèi)存管理
假如Button類有一個void (^blockName)()的屬性
// Button的頭文件
@interface Button : NSObject
// 編譯器自動生成變量名為_ButtonBlock的變量
@property (nonatomic, copy) void (^ButtonBlock)();
@end
通過上面學(xué)習(xí)的類型聲明,我們也可以這樣寫
typedef void (^ButtonBlock)();
@interface Button : NSObject
// 編譯器自動生成變量名為_buttonBlock的變量
@property (nonatomic, copy) ButtonBlock buttonBlock;
@end
block作為一個類成員屬性類成員屬性,iOS開發(fā)中最常用的就是監(jiān)聽控件的事件,實(shí)現(xiàn)類似java中的回調(diào)函數(shù)功能。
下面代碼是模擬Button點(diǎn)擊后調(diào)用Button的監(jiān)聽器(Block)
typedef void (^ButtonBlock)();
@interface Button : NSObject
@property (nonatomic, copy) ButtonBlock buttonBlock;
// 模擬點(diǎn)擊事件
- (void)click;
@end
@implementation Button
- (void)click{
_buttonBlock(); // 按鈕點(diǎn)擊后調(diào)用按鈕的block
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Button *button = [[Button alloc] init];
// button的點(diǎn)擊監(jiān)聽器
button.ButtonBlock = ^(){
NSLog(@"button被點(diǎn)擊了");
};
[button click]; // 打印button被點(diǎn)擊了
}
return 0;
}