標籤:
第二章 Blocks
2.1 Blocks摘要
Blocks是C語言的擴充功能,是帶有自動變數(局部變數)的匿名函數。Blocks儲存自動變數的值.Blocks不是Objective-c專屬的概念,在其他語言中(如Smalltalk或Ruby)也有對應的概念。
2.2 Blocks模式
2.2.1 Block文法^ 返回值類型 參數列表 運算式返回值類型可以省略^ 參數列表 運算式參數列表也可以省略^ 運算式
2.2.2 Block類型變數可將Block文法賦值給聲明為Block類型的變數中。如:int (^aBlock)(int)=^(int count){return count+1;};也可以由Block類型變數向Block類型變數賦值,如int(^bBlock)(int)=aBlock;Block類型變數可作為函數參數,如void func(int (^block)(int)){}Block類型變數作為函數返回值:int (^func())(int){return ^(int count){return count+1;};}Block定義與函數指標定義類似,對比c語言中函數指標作為函數返回值理解:
指向函數的指標:可以仿照上邊基礎資料型別 (Elementary Data Type)的定義 例如:void (*p)() =function; (funciton是某個定義好的函數) 格式:函數類型 *指標變數名 = 函數名; 說明:由於p指標是指向函數的,所以(*p)()中的紅色小括弧必須有,因為函數本身是要參數的,即使沒有參數也要寫(); 如果p指向的函數有參數:int (*pp)(int, int) = sum; 調用指向函數的指標: 無參:p(); 有參:int sum = pp(2,3);block的定義和使用,和指向函數的指標格式很像 例如:void (^firstBlock)() = ^(){...代碼...}; 說明:藍色的小括弧可以不寫,有參數的時候必須寫 格式:block類型 ^block名稱 = ^{程式碼片段}; 有參數block:int (^multiBlock)(int, int) = ^(int a, int b){ return a * b; }; 調用block:無參:firstBlock() 有參:int result = multiBlock(2, 3); 函數指標作為函數返回值:void (*fun1(double d))(int, char){ printf("%f\n",d); return fun;} |
使用typedef可以使block在使用時更為簡潔。typedef int (^blk_t)(int);我們可以對比一下:void func(int (^block)(int)){} ——> void func(blk_t blk){}int (^func())(int){} ——> blk_t func(){}
調用Block方法和調用C語言函數類似。Block類型的變數完全可像C語言變數一樣使用,因此可以使用指向Block類型變數的指標,即Block指標類型變數。blk_t blk=^(int count){return count+1};blk_t *blkptr=&blk;(*blk_ptr)(10);
2.2.3 截獲自動變數值
int temp=2; void (^myBlk)(void)=^(){printf(“%d",temp);}; temp=100; myBlk();結果是 2;Block運算式截獲所使用自動變數(局部變數)的值。
2.2.4 __block說明符Block只能截獲自動變數的瞬間值,並不能改變自動變數的值。想要在Block的運算式中將值賦給Block文法外聲明的自動變數,需要在該變數前附加 __block說明符,該變數稱為 __block變數;
__block int temp=2;
void (^myBlk)()=^(){
temp+=8;
};
myBlk(); printf("----%d",temp);2.2.5 截獲的自動變數截獲自動變數的值是不能被修改的,但是截獲OC對象(如NSMutableArray)時,向數組中增加元素是可以的,而直接賦值是不行的。也就是可以使用,不可以進行賦值。要進行賦值,同樣需要添加__block修飾符。在使用C語言數組時應注意,截獲自動變數的方法並沒有實現對C語言數組的截獲。如下面代碼:
constchar text[]="zyb";
void(^blk)(void)=^{
printf("%c",text[2]); };
會提示錯誤:Cannot refer to declaration with an array type inside block。可以使用指標解決該問題:constchar *text="zyb";
void(^blk)(void)=^{
printf("%c",text[2]); };
[讀書筆記]iOS與OS X多線程和記憶體管理 [Blocks部分-1]