iOS中block簡介-做用域

轉: http://www.2cto.com/kf/201401/269467.html

用block能夠定義任意的代碼片斷,將其像對象同樣傳入另外一個方法;它是c級別的語法,和C語言中的函數指針很是類似。在C語言中,函數指針和block寫法分別以下html

 

 
1
2
    int (* func1)( int a, int b); //c函數指針
返回類型 | 函數名 | 參數
 
1
2
int (^backValue)( int num); //block
返回類型 | 方法名  |  參數
從表面來看二者惟一的區別就在於*和^。一般來講,block都是一些簡短代碼片斷的封裝,適用作工做單元,一般用來作併發任務、遍歷以及回調。

block對象也是對象,實例化方法以下java

 

?
1
2
3
int (^backValue)( int ) = ^( int num) {
     return num+ 1 ;
};

block須要注意的一個特性就是"Variable Capturing",直譯過來就是捕捉變量。block會將「捕捉」到的變量複製一份,而後對複製品進行操做,這是很是重要的一點。對於如下代碼來講打印結果是b-->2,這是由於在block做用域內會複製a,而後對複製的a進行操做,做用域外的a就不會產生變化,因此,在a++;以後再調用backValue(1),結果是2併發

 

 
1
2
3
4
5
6
7
int a = 1 ;
int (^backValue)( int ) = ^( int num) {
     return num+a;
};
a += 1 ;
int b = backValue( 1 );
NSLog(@ "b-->%d" , b);

若是但願block做用域內能夠修改外邊的變量,可使用__block(注意是兩個下劃線)來修飾int a。這樣以來結果就會是b-->3。

 

 

剛纔的例子中a是一個基本類型的變量,若是block外是一個oc對象的話,結果就又不同了,好比下邊代碼,結果就是"block做用域內賦值"函數

 

 
1
2
3
4
5
6
7
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake( 10 , 300 , 300 , 40 )];
label.text = @ "block做用域外賦值" ;
void (^backValue)(NSString *) = ^(NSString *str) {
     label.text = str;
};
backValue(@ "block做用域內賦值" );
[self.view addSubview:label];

這是由於UILabel *label;定義了一個對象指針,在block做用域內複製的是label這個指針,而不是對象,複製以後的指針仍然指向原來的對象,因此對label.text進行操做是能夠修改原對象的,可是做用域內若是想下邊這樣寫就不行了,會獲得提示Variable is not assignable。

 

1
label = [[UILabel alloc] init];
相關文章
相關標籤/搜索