天天看點

Objective-C的Block聲明:正文:參考:

聲明:

1、如果文章内容涉及到其他已經發表了,但文章中又未提及轉載事項,請及時與本人聯系。

2、本文為個人了解,如果部分知識點與真實情況有出入,請忽略本文。

3、如本文解釋有任何問題導緻您的損失,概不負責。

4、本文是寫給小白的,大神可以忽略,或者提點意見,但是……不要(或者輕點)噴。

正文:

1 了解Block

1.1 概念

(1)帶有局部變量的匿名函數(代碼塊)。

(2)使用Blocks可以不聲明C++和Objective-C類,也沒有使用靜态變量、靜态全局變量或全局變量時的問題,僅用編寫C語言函數的源代碼量即可使用帶有局域變量的匿名函數。

1.2 文法

(1)^【傳回值類型】【(參數清單)】表達式

*其中“【】”内的内容為可省略内容。

(2)其中,傳回值類型、參數清單都可以省略。即使有傳回值,也可省略傳回值類型,編譯器會自動識别傳回值類型(NSObject或者void)。

例如:

^void (id testObj) {
       testObj= [[NSString alloc] initWithString:@"This is a iOS Block test!"];
       NSLog(@”%@”,testObj);
}
           

(3)建立Block,其實是系統自動建立了一個函數,而Block的指派其實就是将該函數的指針進行存儲、傳遞,類似函數指針指派(Block指派,下文會講到)。

2 Block的用法

2.1 Block類型變量

在Block文法下,可将Block代碼塊指派給Block類型的變量。即整個Block代碼塊可以作為“值”指派,指派對象為聲明為Block類型的變量。

2.1.1 以Block的傳回值作為指派對象

這種類型再熟悉不過,與普通的函數類似,将函數中return的值作為指派對象。

例如:

int testInt = ^int {
       return7;
};
           

2.1.2 以Block作為指派對象

(1)在Block文法下,可将Block代碼塊指派給已聲明為Block類型的變量。

例如:

//聲明Block類型變量
int (^testBlk)(int);
//聲明Block類型變量,文法為“傳回值類型 (^Block代碼塊名稱)【(參數類型清單)】”
//将Block代碼塊指派給Block類型變量
testBlk = ^(int count){
       returncount + 1;
};
           

(2)在Block文法下,可将Block代碼塊作為函數的傳遞參數。

例如:

void testFunction(Bool testBool, int (^testBlk)(int)){
       if(testBool) {
              testBlk;
	}
}
           

(3)在Block文法下,可将Block代碼塊作為函數的傳回值。

例如:

int (^testBlk)(int) testFunction(){
       return^(int count) { return count + 1;};
}
           

(4)用typedef聲明Block類型,利于代碼可讀性。

例如:

//聲明Block類型,作為Block的參數類型
typedef int (^testBlockType)(int);
int testInt = 0;
//作為傳遞參數時
void testFunction(testBlockType testBlk){
       testBlk= ^(int count) { return count + 1;};
       testInt= testBlk(10);
}
//作為傳回值時
testBlockType testFunction(){
       return(^(int count) { return count + testInt;});
}
           

2.2 在Block中,截獲自動變量

在Block的代碼塊中,截獲代碼塊之外的變量,其變量值、使用方式須遵守Block文法的規則。

2.2.1截獲自動變量

(1)Block中,Block代碼塊截獲的自動變量值,是儲存在該自動變量的瞬間值。

例如:

int testInt = 0;
void (^blk)() = ^{printf(“value = %d”,testInt)};
blk();
//此處列印結果為:value = 0
testInt = 1;
blk();
//此處列印結果為:value = 0
           

(2)Block中,截獲自動變量後,不能改寫該變量的值。

例如:

int testInt = 0;
void (^blk)() = ^{ testInt = 1;};
blk();
//此處報錯。在Block代碼塊中,無法改寫非該Block内部自動變量的值。
           

2.2.2 __block說明符

如果需要在Block代碼塊中改寫該Block之外的自動變量的值,需要在該自動變量上附加__block說明符。

例如:

__block int testInt = 0;
void (^blk)() = ^{ testInt = 1;};
blk();
           

參考:

《Objective-C進階程式設計iOS與OS X多線程和記憶體管理》【日】KazukiSakamoto  Tomohiko Furumoto 著  黎華 譯