IOS中 Block簡介與用法(一)
http://blog.csdn.net/enuola/article/details/8674063
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.
未完待續。。
相關文章
- IOS中 Block簡介與用法iOSBloC
- IOS Block 塊用法iOSBloC
- ios中XMPPFramework 簡介iOSFramework
- InfluxDB簡介與php用法UXPHP
- Shell中Read用法簡介
- iOS KVC與KVO簡介iOS
- xml schema 中elementFormDefault 的用法簡介XMLORM
- iOS block巢狀block中weakify的使用iOSBloC巢狀
- iOS中Block的用法,示例,應用場景,與底層原理解析(這可能是最詳細的Block解析)iOSBloC
- AWK用法簡介
- iOS - Block探究系列一iOSBloC
- iOS IB_DESIGNABLE 和 IBInspectable 用法簡介iOS
- C#中HashTable簡介和使用用法C#
- iOS 12 中的 Siri Shortcuts 簡介iOS
- expdp 的用法簡介
- ObjC block簡析(一)OBJBloC
- 簡單介紹SQLserver中的declare變數用法SQLServer變數
- js迴圈中reduce的用法簡單介紹JS
- Varnish(一)簡介與原理
- Hbase簡介和基本用法
- mysqladmin的用法簡介MySql
- Oracle Scheduler(1)用法簡介Oracle
- start with ... connect by用法簡介
- AVFoundation (iOS) 簡介iOS
- Nagios簡介iOS
- PostgreSQL中索引與CTE簡介SQL索引
- 探索iOS中Block的實現原理iOSBloC
- js的邏輯與&&運算子用法簡單介紹JS
- 簡單介紹Python中異常處理用法Python
- javascript中的就加號+的用法簡單介紹JavaScript
- iOS-一張圖看清ReactiveCocoa簡介iOSReact
- iOS 中 cell的用法iOS
- iOS Block探究iOSBloC
- iOS--BlockiOSBloC
- RxJava簡介與入門(一)RxJava
- jQuery filter() 用法簡單介紹jQueryFilter
- javascript的this用法簡單介紹JavaScript
- js WebSocket用法簡單介紹JSWeb