OC加入代碼塊的功能,可以將一塊代碼當(dāng)做一個對象一樣對待,并且傳遞給其他方法或函數(shù).代碼塊支持在代碼中定義一個函數(shù)對象,這個函數(shù)對象可以通過傳統(tǒng)的變量來引用,也可以將其傳入到其他函數(shù),這就意味著,你可以定義可復(fù)用的代碼段,并且可以向?qū)ο笠粯拥教巶鬟f從而動態(tài)地在其他對象內(nèi)部執(zhí)行.這聽起來可能讓你有點迷惑,不過沒有關(guān)系,通過這里的幾個例子,你可以輕松的理解并能夠使用代碼塊,它遠沒有你想象的那么難
代碼塊本質(zhì)上適合其他變量類似.不同的是,代碼塊存儲的數(shù)據(jù)是一個函數(shù)體,脫字符(^)是代碼塊的語法標(biāo)記,按照我們熟悉的語法規(guī)約定義返回值绅这、參數(shù)以及代碼塊的主體(也就是可以執(zhí)行的代碼).首先我們來看一個最最簡單的代碼塊的示例:
//代碼塊聲明
void(^Block)(NSString *x);
//代碼塊變量賦值(代碼塊變量中存的是函數(shù)體)
aBlock = ^(NSString *x){
???? NSLog(@"%@",x);
}
代碼塊變量的聲明要比普通變量聲明復(fù)雜,普通變量聲明不需要傳入?yún)?shù),并且沒有返回值.也因為代碼塊變量存儲的數(shù)據(jù)是一個函數(shù)體,所以聲明代碼塊變量時需要聲明參數(shù)和返回類型,對于一個代碼塊變量的聲明,可以這么做:
?? 語法:
?????? 返回值類型(^代碼塊名字)(參數(shù)列表);
分析上面的代碼,注意第8行代碼,聲明了一個保存代碼塊的變量aBlock,最前面的void 說明代碼塊執(zhí)行時沒有返回值.緊跟著返回值類型定義的是一個特殊操作符,它告訴編譯器所定義的是代碼塊而不是其他類型的變量,這個操作字符就是多字符(^).
在^字符之后,給出了存儲代碼塊的變量名 aBlock,這個變量名同脫字符(^)一起使用小括號同其后的參數(shù)隔開.
提示:在列出參數(shù)時,無需提供參數(shù)的變量名,是否提供變量名由你來決定,但這不是必須的.也許這樣理解比較好:目前還沒有聲明函數(shù)體,所以提供參數(shù)的變量名沒有任何作用,因為暫時不會用到它.你僅需告訴編譯器參數(shù)的類型即可,多個參數(shù)類型要以逗號隔開.很多代碼塊的文檔在聲明時都省略了參數(shù)名,但我不會這樣做,因為我覺得這樣的代碼會使初學(xué)者迷惑.
記得最后要以分號結(jié)束語句.到目前為止,我們聲明了一個變量aBlock,用于存儲代碼塊.它接收指定參數(shù)并返回指定的值類型.
但是,僅僅聲明變量是不夠的.我們需要給這個代碼塊變量賦值,那么給代碼塊賦值的時候,可以這么做:
語法:
???? 代碼塊名字 = ^(參數(shù)列表) {代碼塊的行為主體};
//代碼塊變量聲明的同時賦值
int mulitplier = 7;
int(^myBlock)(int) = ^(int num){
???? return num *mulitplier;
};
void(^aVoidBlock)() = ^{
????? NSLog(@"I am a aVoidBlock!");
}
聲明和實現(xiàn):
//代碼塊的聲明
double(^getArea)(double width,double height);
//代碼塊的實現(xiàn)
getArea = ^(double width,double height){
double area = width * height;
return area;
};
double area = getArea(5,10);
NSLog(@"area = %.2f",area);