標籤:
Block代碼塊是對C做出的一個補充,初次體驗代碼塊,無比的不適應。古怪的文法確實讓人不易入門甚至精通。但若能夠深入精通Block的使用,會給代碼帶來層次上的提升。Block就是一段在將來被執行的代碼
定義塊文法
^[塊傳回值類型](形參類型1 形參1,形參類型2 形參2,...) { //塊執行任務 }
需要注意的是定義塊必須以^開頭定義塊變數
塊傳回值類型 (^塊變數名)(形參類型1,形參類型2,...);
簡單一實例
//定義塊變數 void(^NSLogStr)(); //通過塊變數調用塊 NSLogStr=^(void) { };
//定義無傳回值不帶參數 void (^NSLogStr)()=^() { //代碼塊實現的方法 NSLog(@"Hello Block"); }; //通過代碼變數調用代碼塊 NSLogStr();
局部變數
- 在預設狀態,當用塊訪問局部變數的值時候,是不允許修改局部變數的。
但當為局部變數加上 __block修飾就可以修改局部變數
__block int a=10; void (^NSLogStr)()=^() { //讀取局部變數a,是可以的 NSLog(@"%d",a); //試圖修改局部變數,錯誤的。無法運行通過 a=20; NSLog(@"%d",a); NSLog(@"Hello Block"); }; //通過代碼變數調用代碼塊 NSLogStr();
2016-05-01 16:20:23.860 [2470:103092] 102016-05-01 16:20:23.861 [2470:103092] 202016-05-01 16:20:23.861 [2470:103092] Hello Block
- 看下面代碼
int a=10; void (^NSLogStr)()=^() { //讀取局部變數a,是可以的 NSLog(@"%d",a); NSLog(@"Hello Block"); }; a=30; //通過代碼變數調用代碼塊 NSLogStr(); NSLog(@"%d",a);
猜猜應該列印的值是多少?兩個a都是30?
2016-05-01 16:27:57.600 [2543:107259] 102016-05-01 16:27:57.601 [2543:107259] Hello Block2016-05-01 16:27:57.601 [2543:107259] 30
Why?
原來,在定義代碼塊時就已經把局部變數的值複製到塊 。所以即使在定義後、調用前修改局部變數,依然是沒有用的。 倘若我們我們想等到執行時才去訪問擷取甚至去修改局部變數的值,我們可以在局部變數前面加__block
Block進階用法代碼塊作為函數的參數(只能當函數的最後一個參數)
這時候我們需要引入一個typedef用typedef可以定義代碼塊類型,主要有兩個作用
-
複用塊變數類型,使用塊變數類型可以重複定義多個塊變數
-
使用塊變數類型定義函數參數,這樣可定義帶塊參數的函數
typedef 塊傳回值類型(^塊變數類型)(形參類型1,形參類型2,....);
定義一個函數,Block作為函數最後一個參數
typedef NSString* (^LogStr)(NSString *);void NSLogStr(NSString *name,LogStr log){ NSLog(@"%@%@",log(name),@",歡迎您");}調用: NSString *[email protected]"喬布斯"; NSLogStr(name, ^NSString *(NSString *name) { return name; });
代碼塊取代代理傳值
Block用法解析