IOS中的Block與C++11中的lambda,ioslambda

來源:互聯網
上載者:User

IOS中的Block與C++11中的lambda,ioslambda

 ios中的block 可以說是一種函數指標,但更確切的講,其實際上其應該算是object-c對C++11中lambda的支援或者說是一個語言上的變體,其實際內容是一樣的,C++的lambda我已經有簡介過,現在說下ios中的block

Block的實際行為和Function很像,最大的差別是在可以存取同一個Scope的變數值。Block實體形式如下:

^(傳入參數列){行為主體};

Block實體開頭是“^”,接著是由小括弧所包起來的參數列(比如 int a, int b, int c),return a*a;};  
這是代表Block會回傳輸入值的平方值(int a 就是參數列, return a*a; 就是行為主體)。記得行為主體裡最後要加“;”,因為是敘述,而整個{}最後也要加“;”,因為Block是物件實體。用法如下:

  1. int result = ^(int a){return a*a;}(5);  
  2. NSLog(@"%d", result);  


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

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

Block Pointer是這樣定義的:

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

比如下面的例子:

  1. //聲明一個square的Block Pointer,其所指向的Block有一個int輸入和int輸出  
  2. int (^square)(int);  
  3. //將Block實體指定給square  
  4. square = ^(int a){ return a*a ; };  
  5. //調用方法,感覺是是不是很像function的用法?  
  6. int result = square(5);  
  7. NSLog(@"%d", result);  

是不是變的簡單了?

也可以吧Block Pointer當成參數傳遞給一個function,比如:

  1. void myFunction(int (^mySquare)(int));     //function的定義,將Block作為參數  
  2. int (^mySquare)(int) = ^(int a){return a*a;};   //定義一個mySquare的Block pointer變數  
  3. myFunction(mySquare);    //把mySquare作為myFunction的參數  


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

  1. myFunction( ^int(int a){return a*a;} );  


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

  1. -(void)objcMethod:(int(^)(int))square;  //square參數的類型是int(^)(int)  


存取變數

1、可以讀取和Block pointer同一個Scope的變數值:

  1. {  
  2.     int outA = 8;  
  3.     int (^myPtr)(int) = ^(int a){ return outA + a;};  
  4.     //block裡面可以讀取同一類型的outA的值  
  5.     int result = myPtr(3);  // result is 11  
  6.     NSLog(@"result=%d", result);  
  7. }  


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

  1. {  
  2.     int outA = 8;  
  3.     int (^myPtr)(int) = ^(int a){ return outA + a;}; //block裡面可以讀取同一類型的outA的值  
  4.       
  5.     outA = 5;  //在調用myPtr之前改變outA的值  
  6.     int result = myPtr(3);  // result的值仍然是11,並不是8  
  7.     NSLog(@"result=%d", result);  
  8. }  


為什麼result 的值仍然是11?而不是8呢?事實上,myPtr在其主體中用到的outA這個變數值的時候做了一個copy的動作,把outA的值copy下來。所以,之後outA即使換成了新的值,對於myPtr裡面copy的值是沒有影響的。

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

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

  1. {  
  2.     NSMutableArray *mutableArray = [NSMutableArray arrayWithObjects:@"one", @"two", @"three", nil];  
  3.     int result = ^(int a){[mutableArray removeLastObject]; return a*a;}(5);  
  4.     NSLog(@"test array :%@", mutableArray);  
  5. }  


原本mutableArray的值是{@"one",@"two",@"three"},在block裡面被更改mutableArray後,就變成{@"one", @"two"}了。

2、直接存取static類型的變數

  1. {  
  2.     static int outA = 8;  
  3.     int (^myPtr)(int) = ^(int a){return outA + a;};  
  4.     outA = 5;  
  5.     int result = myPtr(3);  //result的值是8,因為outA是static類型的變數  
  6.     NSLog(@"result=%d", result);  
  7.       
  8. }  

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

  1. {  
  2.     static int outA = 8;  
  3.     int (^myPtr)(int) = ^(int a){ outA = 5; return outA + a;};  
  4.     int result = myPtr(3);  //result的值是8,因為outA是static類型的變數  
  5.     NSLog(@"result=%d", result);  
  6.       
  7. }  


3、Block Variable類型的變數

在某個變數前面如果加上修飾字“__block”的話(注意,block前面有兩個底線),這個變數就稱作block variable。

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

  1. {  
  2.     __block int num = 5;  
  3.       
  4.     int (^myPtr)(int) = ^(int a){return num++;};  
  5.     int (^myPtr2)(int) = ^(int a){return num++;};  
  6.     int result = myPtr(0);   //result的值為5,num的值為6  
  7.     result = myPtr2(0);      //result的值為6,num的值為7  
  8.     NSLog(@"result=%d", result);    
  9.   
  10. }  


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


iOS中的block可以代替delegate

可以!,如果簡單傳值,用block不錯
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.