IOS中 Block簡介與用法
Block簡介:
Block的實際行為和Function很像,最大的差別是在可以存取同一個Scope的變數值。Block實體形式如下:
^(傳入引數列){行為主體};
Block實體開頭是“^”,接著是由小括號所包起來的引數列(比如 int a, int b, int c),行為主體由大括號包起來,專有名字叫做block literal。行為主體可以用return回傳值,型別會被compiler自動辨別。如果沒有引數列要寫成: ^(void)。
例如下面的一個例子:
- ^(int a){return a*a;};
這是代表Block會回傳輸入值的平方值(int a 就是引數列, return a*a; 就是行為主體)。記得行為主體裡最後要加“;”,因為是敘述,而整個{}最後也要加“;”,因為Block是物件實體。用法如下:
- int result = ^(int a){return a*a;}(5);
- NSLog(@"%d", result);
很奇怪吧?後面的小括號裡面的5會被當成a的輸入值,然後經由Block輸出 5*5 = 25指定給result這個變數。
有沒有簡單一點的方法嗯?不然每次都寫這麼長?有。接下來介紹一個叫做Block Pointer的東西來簡化我們的寫法。
Block Pointer是這樣定義的:
回傳值(^名字)(引數列);
比如下面的例子:
- //宣告一個square的Block Pointer,其所指向的Block有一個int輸入和int輸出
- int (^square)(int);
- //將Block實體指定給square
- square = ^(int a){ return a*a ; };
- //呼叫方法,感覺是是不是很像function的用法?
- int result = square(5);
- NSLog(@"%d", result);
也可以吧Block Pointer當成引數傳遞給一個function,比如:
- void myFunction(int (^mySquare)(int)); //function的定義,將Block作為引數
- int (^mySquare)(int) = ^(int a){return a*a;}; //定義一個mySquare的Block pointer變數
- myFunction(mySquare); //把mySquare作為myFunction的引數
上面的三行程式碼其實等價於下面這行程式碼:
- myFunction( ^int(int a){return a*a;} );
當其作為Object-C method的傳入值的話,需要把型別寫在變數前面,然後加上小括號。比如下面這種寫法:
- -(void)objcMethod:(int(^)(int))square; //square引數的型別是int(^)(int)
存取變數
1、可以讀取和Block pointer同一個Scope的變數值:
- {
- int outA = 8;
- int (^myPtr)(int) = ^(int a){ return outA + a;};
- //block裡面可以讀取同一型別的outA的值
- int result = myPtr(3); // result is 11
- NSLog(@"result=%d", result);
- }
下面來看一段很有意思的程式碼:
- {
- int outA = 8;
- int (^myPtr)(int) = ^(int a){ return outA + a;}; //block裡面可以讀取同一型別的outA的值
- outA = 5; //在呼叫myPtr之前改變outA的值
- int result = myPtr(3); // result的值仍然是11,並不是8
- NSLog(@"result=%d", result);
- }
為什麼result 的值仍然是11?而不是8呢?事實上,myPtr在其主體中用到的outA這個變數值的時候做了一個copy的動作,把outA的值copy下來。所以,之後outA即使換成了新的值,對於myPtr裡面copy的值是沒有影響的。
需要注意的是,這裡copy的值是變數的值,如果它是一個記憶體的位置(地址),換句話說,就是這個變數是個指標的話,
它的值是可以在block裡被改變的。如下例子:
- {
- NSMutableArray *mutableArray = [NSMutableArray arrayWithObjects:@"one", @"two", @"three", nil];
- int result = ^(int a){[mutableArray removeLastObject]; return a*a;}(5);
- NSLog(@"test array :%@", mutableArray);
- }
原本mutableArray的值是{@"one",@"two",@"three"},在block裡面被更改mutableArray後,就變成{@"one", @"two"}了。
2、直接存取static型別的變數
- {
- static int outA = 8;
- int (^myPtr)(int) = ^(int a){return outA + a;};
- outA = 5;
- int result = myPtr(3); //result的值是8,因為outA是static型別的變數
- NSLog(@"result=%d", result);
- }
甚至可以直接在block裡面修改outA的值,例如下面的寫法:
- {
- static int outA = 8;
- int (^myPtr)(int) = ^(int a){ outA = 5; return outA + a;};
- int result = myPtr(3); //result的值是8,因為outA是static型別的變數
- NSLog(@"result=%d", result);
- }
3、Block Variable型別的變數
在某個變數前面如果加上修飾字“__block”的話(注意,block前面有兩個下劃線),這個變數就稱作block variable。
那麼在block裡面就可以任意修改此變數的值,如下程式碼:
- {
- __block int num = 5;
- int (^myPtr)(int) = ^(int a){return num++;};
- int (^myPtr2)(int) = ^(int a){return num++;};
- int result = myPtr(0); //result的值為5,num的值為6
- result = myPtr2(0); //result的值為6,num的值為7
- NSLog(@"result=%d", result);
- }
因為myPtr和myPtr2都有用到num這個block variable,最終num的值為7.
轉自:http://blog.csdn.net/enuola/article/details/8674063
感謝 enuola
相關文章
- InfluxDB簡介與php用法UXPHP
- iOS KVC與KVO簡介iOS
- iOS block巢狀block中weakify的使用iOSBloC巢狀
- iOS中Block的用法,示例,應用場景,與底層原理解析(這可能是最詳細的Block解析)iOSBloC
- iOS Block探究iOSBloC
- iOS 12 中的 Siri Shortcuts 簡介iOS
- 探索iOS中Block的實現原理iOSBloC
- iOS 中的 block 是如何持有物件的iOSBloC物件
- iOS中Block實現原理的全面分析iOSBloC
- 簡單介紹SQLserver中的declare變數用法SQLServer變數
- 簡單介紹Python中異常處理用法Python
- js迴圈中reduce的用法簡單介紹JS
- iOS 中 cell的用法iOS
- iOS Block淺淺析iOSBloC
- iOS - Block探究系列一iOSBloC
- iOS block 反向傳值iOSBloC
- PostgreSQL中索引與CTE簡介SQL索引
- iOS 檔案操作簡介iOS
- 簡單說說iOS之WKWebView的用法iOSWebView
- linux命令下jq的用法簡介Linux
- iOS探索:Block解析淺談iOSBloC
- iOS Block學習筆記iOSBloC筆記
- iOS CocoaPods簡介及基本使用iOS
- MSSQL Sql加密函式 hashbytes 用法簡介SQL加密函式
- iOS - 對 block 實現的探究iOSBloC
- ObjC block簡析(一)OBJBloC
- mssql sqlserver update delete表別名用法簡介SQLServerdelete
- Java Math floor,ceil,rint及round用法簡介Java
- iOS底層原理 - Block本質探究iOSBloC
- iOS-block本質是什麼?iOSBloC
- [iOS] Socket & CocoaAsyncSocket介紹與使用iOS
- js中的||與&&用法JS
- ios簽名證書簡單介紹iOS
- Vue腳手架介紹與基本用法Vue
- Systemd簡介與使用
- JQuery簡介與使用jQuery
- HTTP 與 HTTPS 簡介HTTP
- 『簡書API:jianshu 基於golang -- 用法介紹 (2)』APIGolang
- Golang | 簡介channel常見用法,完成goroutin通訊Golang