IOS中 Block簡介與用法(一)

2021-06-22 09:03:35 字數 3823 閱讀 2683

block簡介:

block的實際行為和function很像,最大的差別是在可以訪問同乙個scope的變數值。block實體形式如下:

^(傳入引數列);

block實體開頭是「^」,接著是由小括號所包起來的引數列(比如 int a, int b, int c),行為主體由大括號包起來,專有名字叫做block literal。行為主體可以用return回傳值,型別會被compiler自動辨別。如果沒有引數列要寫成: ^(void)。

例如下面的乙個例子:

[cpp]view plain

copy

^(int

a);  

這是代表block會回傳輸入值的平方值(

int a

就是引數列

,return a*a;

就是行為主體

)。記得行為主體裡最後要加「;」,因為是敘述,而整個{}最後也要加「;」,因為block是物件實體。用法如下:

[cpp]view plain

copy

intresult = ^(

inta)(5);  

nslog(@"%d"

, result);  

很奇怪吧?後面的小括號裡面的5會被當成a的輸入值,然後經由block輸出 5*5 = 25指定給result這個變數。

有沒有簡單一點的方法嗯?不然每次都寫這麼長?有。接下來介紹乙個叫做block pointer的東西來簡化我們的寫法。

block pointer是這樣定義的:

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

比如下面的例子:

[cpp]view plain

copy

//宣告乙個square的block pointer,其所指向的block有乙個int輸入和int輸出

int(^square)(

int);  

//將block實體指定給square

square = ^(int

a);  

//呼叫方法,感覺是是不是很像function的用法?

intresult = square(5);  

nslog(@"%d"

, result);  

是不是變的簡單了?

也可以吧block pointer當成引數傳遞給乙個function,比如:

[cpp]view plain

copy

void

myfunction(

int(^mysquare)(

int));     

//function的定義,將block作為引數

int(^mysquare)(

int) = ^(

inta);   

//定義乙個mysquare的block pointer變數

myfunction(mysquare);    //把mysquare作為myfunction的引數

上面的三行**其實等價於下面這行**:

[cpp]view plain

copy

myfunction( ^

int(

inta) );  

當其作為object-c method的傳入值的話,需要把型別寫在變數前面,然後加上小括號。比如下面這種寫法:

[cpp]view plain

copy

-(void

)objcmethod:(

int(^)(

int))square;  

//square引數的型別是int(^)(int)

訪問變數

1、可以讀取和block pointer同乙個scope的變數值:

[cpp]view plain

copy

;  //block裡面可以讀取同一型別的outa的值

intresult = myptr(3);  

// result is 11

nslog(@"result=%d"

, result);  

}  

下面來看一段很有意思的**:

[cpp]view plain

copy

; //block裡面可以讀取同一型別的outa的值

outa = 5;  //在呼叫myptr之前改變outa的值

intresult = myptr(3);  

// result的值仍然是11,並不是8

nslog(@"result=%d"

, result);  

}  

為什麼result 的值仍然是11?而不是8呢?事實上,myptr在其主體中用到的outa這個變數值的時候做了乙個copy

的動作,把outa的值copy下來。所以,之後outa即

使換成了新的值,對於myptr裡面copy的值是沒有影響的。

需要注意的是,這裡copy的值是變數的值,如果它是乙個記憶體的位置(位址),換句話說,就是這個變數是個指標的話,

它的值是可以在block裡被改變的。如下例子:

[cpp]view plain

copy

(5);  

nslog(@"test array :%@"

, mutablearray);  

}  

原本mutablearray的值是,在block裡面被更改mutablearray後,就變成了。

2、直接訪問static型別的變數

[cpp]view plain

copy

;  outa = 5;  

intresult = myptr(3);  

//result的值是8,因為outa是static型別的變數

nslog(@"result=%d"

, result);  

}  

甚至可以直接在block裡面修改outa的值,例如下面的寫法:

[cpp]view plain

copy

;  int

result = myptr(3);  

//result的值是8,因為outa是static型別的變數

nslog(@"result=%d"

, result);  

}  

3、block variable型別的變數

在某個變數前面如果加上修飾字「_

_block」的話(注意,block前面有兩個下劃線),這個變數就稱作block variable。

那麼在block裡面就可以任意修改此變數的值,如下**:

[cpp]view plain

copy

;  int

(^myptr2)(

int) = ^(

inta);  

intresult = myptr(0);   

//result的值為5,num的值為6

result = myptr2(0);      //result的值為6,num的值為7

nslog(@"result=%d"

, result);    

}  

因為myptr和myptr2都有用到num這個block variable,最終num的值為7.

IOS中 Block簡介與用法(一)

block簡介 block的實際行為和function很像,最大的差別是在可以訪問同乙個scope的變數值。block實體形式如下 傳入引數列 block實體開頭是 接著是由小括號所包起來的引數列 比如 int a,int b,int c 行為主體由大括號包起來,專有名字叫做block litera...

IOS中 Block簡介與用法(一)

block簡介 block的實際行為和function很像,最大的差別是在可以訪問同乙個scope的變數值。block實體形式如下 傳入引數列 block實體開頭是 接著是由小括號所包起來的引數列 比如 int a,int b,int c 行為主體由大括號包起來,專有名字叫做block litera...

IOS中 Block簡介與用法(一)

block簡介 block的實際行為和function很像,最大的差別是在可以訪問同乙個scope的變數值。block實體形式如下 傳入引數列 block實體開頭是 接著是由小括號所包起來的引數列 比如 int a,int b,int c 行為主體由大括號包起來,專有名字叫做block litera...