[讀書筆記]iOS與OS X多線程和內存管理 [Blocks部分-1]

第二章 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語言中函數指針作爲函數返回值理解:

指向函數的指針:可以仿照上邊基本數據類型的定義
  例如: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 inttemp=2;
    void (^myBlk)()=^(){
        temp+=8;
    };
    myBlk();
    printf("----%d",temp);

2.2.5 截獲的自動變量
截獲自動變量的值是不能被修改的,但是截獲OC對象(如NSMutableArray)時,向數組中增加元素是可以的,而直接賦值是不行的。也就是可以使用,不可以進行賦值。要進行賦值,同樣需要添加__block修飾符。
在使用C語言數組時應注意,截獲自動變量的方法並沒有實現對C語言數組的截獲。如下面代碼:

const char text[]="zyb";
    void(^blk)(void)=^{
        printf("%c",text[2]);
    };


會提示錯誤:Cannot refer to declaration with an array type inside block。可以使用指針解決該問題:
const char*text="zyb";
    void(^blk)(void)=^{
        printf("%c",text[2]);
    };

Blocks簡介到此,下一篇文章將會寫Blocks的實現。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章