天天看點

IOS中 Block簡介與用法

block的簡介

個人覺得,block感覺和function有點像,不同的是,函數不可以當做參數進行傳遞,但是block可以當做參數進行傳遞,而且block也可以存取一個scope的值。

block的定義

定義:^(參數清單){實作方法}

block的實體開頭是^,接下來是參數清單(float a,int b,int c),接下來是實作方法{return a+b+c};當然如果沒有參數的話,你可以寫成^(void){};或者寫成^{};

例子:

**

  • 由于block是叙述性語言,最後必須加上”;”,以為block是物體實體。
  • 而且請加上{}和^

**

block的Block Pointer

可能大家覺得郁悶的是,為什麼block沒有傳回類型的呢?當然block也有類似函數的先聲明性質。

Block Pointer 定義

回傳值(^名字)(參數列);

具體使用:

//聲明一個block pointer,其中實作名為size,指向int a,int b。
int ^(size)(int a,int b);
//實作block的執行個體
size =^(int a,int b){return a*b};
//調用size執行個體
int result =size(,);
//輸出資料
printf(@"%d",result);
           

block pointer的函數參數調用

//函數聲明
void count(int ^(size)(int a,int b));
//定義一個名叫size的block pointer的變量
int ^(size)(int a,int b) = ^(int a,int b){return a+b;};
//調用函數
count(size);
           

進行縮減的話

c語言的寫法

count(^int(int a,int b){return a+b;}參數名);
           

OC語言的寫法為:

-(void)count:(int ^(int a ,int b))size;

  • OC中(int ^(int a,int b))就是我們平時見到的修飾類型
  • size也就是參數名

變量的存取

  1. 自動變量
{  
    int outA = ;  
    int (^size)(int) = ^(int a){ return outA + ;};  
    //block裡面可以讀取同一類型的outA的值  
    outA = ; 
    int result = size();  // result is 11  
    NSLog(@"result=%d", result);  
}
           

可能會有人問答案為什麼不是8呢?

**

  • block 在實作時就會對它引用到的它所在方法中定義的棧變量進行一次隻讀拷貝,然後在 block 塊内使用該隻讀拷貝;換句話說block截獲自動變量的瞬時值
  • 或者block捕獲的是自動變量的副本。(block捕獲變量的機制更像是函數按值傳遞)

    就是說block執行個體操作中,并沒有将outA = 5; 這個操作給copy進去。

**

2. 全局變量、靜态變量、全局靜态變量

{  
    static int outA = ;  
    int (^myPtr)(int) = ^(int a){return outA + a;};  
    outA = ;  
    int result = myPtr();  //result的值是8 
    NSLog(@"result=%d", result);  

}  
           

可能會有人問答案為什麼是8呢?

**

  • block 變量其實是一個結構體對象,拷貝的是指向該結構體對象的指針。
  • 靜态變量屬于類的,不是某一個變量。由于block内部不用調用self指針。是以block可以調用。

**

3. 修改自動變量

有人會問如果進行更改自動變量的呢?

答案就是:使用使用__block修飾符

__block int val = ;  
void (^blk)(void) = ^{printf("val=%d\n",val);};  
val = ;  
blk();
           

上面的代碼,跟第一個代碼段相比。隻是多了一個__block修飾符。但是輸出結果确是2了。

__block 變量的内部實作要複雜許多,__block 變量其實是一個結構體對象,拷貝的是指向該結構體對象的指針。

關于block的變量總結

**

  • 不能修改自動變量的值是因為:block捕獲的是自動變量的const值,名字一樣,不能修改
  • 可以修改靜态變量的值:靜态變量屬于類的,不是某一個變量。由于block内部不用調用self指針。是以block可以調用。

**

4.記憶體管理

用這個表格來表示。捕獲變量包括僅僅讀取變量和__block這種寫變量,兩種方式(其實結果是一樣的)

IOS中 Block簡介與用法

在ARC下:似乎已經沒有棧上的block了,要麼是全局的,要麼是堆上的

在非ARC下:存在這棧、全局、堆這三種形式。

參考文章:

http://blog.csdn.net/enuola/article/details/8674063

http://blog.csdn.net/hherima/article/details/38586101