Blocks概要
什么是Block,筆者認為Block其實就是一段代碼塊,這段代碼塊可以嵌入在函數中并且帶有自己的局部變量。
Blocks是C語言的擴充功能??梢杂靡痪湓拋肀硎綛locks的擴充功能:帶有自動變量(局部變量)的匿名函數。
顧名思義,所謂匿名函數就是不帶有名稱的函數。而通過Blocks,源代碼中就能夠使用匿名函數。
Block語法
Block語法基本形式:
^ 返回值類型 參數列表 表達式
^int (int count) {return count + 1;}
Block語法的省略
- Block語法可以省略返回值類型。當省略返回值類型時,如果表達式中有return語句,則使用該返回值類型;如果有多個return語句,則每個語句的返回值類型必須一致;如果沒有返回值,則使用void類型:
^ (int count) { return count + 1; }// 返回值類型為int
^ (int count) { NSLog(@"Hello World!"); }// 返回值類型為void
^ (int count) {
if(count > 1)
return count;
else
return --count;}// 返回值類型為int
^ (int count) {
if(count > 1)
return count;
else
return @"11";}// 錯誤
- 如果不使用參數,參數列表也可以省略
^ { NSLog(@"Hello World!");}
Block類型變量
當我們定義了一段Block代碼塊后,怎么使用呢?這時候就需要用到Block類型變量。Block類型變量的聲明和Block語法塊的頭部差不多(頭部即除去表達式部分)。和Block語法不同是,Block類型變量不能省略。同時,Block類型變量和Block語法塊的返回值類型和參數列表相同。
int (^blk) (int) = ^ (int count){return count + 1;};
int t = blk(10);
NSLog(@"value:%d",t);
運行結果:
運行結果
Block語法特性
- Block可以截獲自動變量
-
__block
說明符 - 截獲的自動變量
截獲自動變量
Blocks中Block表達式截獲所使用的自動變量的值,即保存該自動變量的瞬間值。因為Block表達式保存了自動變量的值,所以在執行Block語法后,即使改寫Block中使用的自動變量的值也不會影響Block執行時的自動變量的值。
int t = 10;
void (^blk) (void) = ^ {NSLog(@"t value is :%d",t);};
t = 0;
blk();
運行結果:
截獲自動變量的值
__block
說明符
Block所截獲的自動變量的值只是執行Block語法瞬間的值,即在執行Block語法的瞬間,自動變量的值是多少Block語法截獲的值就是多少,執行完成Block之后,自動變量的值改變,Block中截獲的值也不會變。且截獲的值只是保存,不能修改。
int t = 10;
void (^blk) (void) = ^ {
t = 3;
NSLog(@"t value is :%d",t);};
t = 0;
blk();
運行結果:
截獲的自動變量不能修改
若我們想要修改其值,需要添加__block
說明符:
__block int t = 10;
void (^blk) (void) = ^ {
t = 3;
NSLog(@"t value is :%d",t);};
t = 0;
blk();
運行結果:
添加__block說明符
截獲的自動變量
當Block語法截獲未添加__block
說明符自動變量后,調用改變量的對象方法不會出錯,但是對自動變量賦值就會出錯。
- 使用對象方法:
id array = [NSMutableArray array];
NSLog(@"%lu",(unsigned long)[array count]);
void (^blk) (void) = ^ {
id objc = [[NSObject alloc] init];
[array addObject:objc];};
blk();
NSLog(@"%lu",(unsigned long)[array count]);
運行結果:
使用自動變量對象方法
- 對自動變量賦值:
id array = [NSMutableArray array];
void (^blk) (void) = ^ {
id array = [NSMutableArray array];};
blk();
運行結果:
修改自動變量
所以,想要修改自動變量還是需要添加__block說明符。
結語
- 關于Block的本質,請參閱Objective-C之Blocks(二)
- 如有錯誤,歡迎指正。
- 參考資料:
[1] Kazuki Sakamoto,Tomohiko Furumoto.Objective-C高級編程〔M〕.北京:人民郵電出版社,2013