国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設計 > 正文

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

2019-11-14 20:08:00
字體:
供稿:網(wǎng)友

 ios中的block 可以說是一種函數(shù)指針,但更確切的講,其實際上其應該算是object-c對C++11中l(wèi)ambda的支持或者說是一個語言上的變體,其實際內(nèi)容是一樣的,C++的lambda我已經(jīng)有簡介過,現(xiàn)在說下ios中的block

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

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

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

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


很奇怪吧?后面的小括號里面的5會被當成a的輸入值,然后經(jīng)由Block輸出 5*5 = 25指定給result這個變量。

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

Block Pointer是這樣定義的:

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

比如下面的例子:

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

是不是變的簡單了?

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

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


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

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


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

  1. -(void)objcMethod:(int(^)(int))square;  //square參數(shù)的類型是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;  //在調(diào)用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.


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 上虞市| 双辽市| 互助| 木里| 平泉县| 台东县| 梁平县| 汉源县| 内江市| 广东省| 台中市| 象山县| 景洪市| 荔波县| 闽侯县| 遂平县| 长沙市| 禹州市| 桑植县| 岳池县| 莱芜市| 象州县| 灵台县| 襄樊市| 清原| 鸡东县| 石屏县| 马龙县| 保定市| 大石桥市| 来凤县| 三门峡市| 百色市| 会昌县| 长乐市| 平果县| 荆门市| 星子县| 丹寨县| 屯昌县| 岑溪市|