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] 10
2016-05-01 16:20:23.861 [2470:103092] 20
2016-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] 10
2016-05-01 16:27:57.601 [2543:107259] Hello Block
2016-05-01 16:27:57.601 [2543:107259] 30
Why?
原來,在定義代碼塊時就已經把局部變量的值復制到塊 。所以即使在定義後、調用前修改局部變量,依然是沒有用的。 倘若我們我們想等到執行時才去訪問獲取甚至去修改局部變量的值,我們可以在局部變量前面加__block
這時候我們需要引入一個typedef
用typedef可以定義代碼塊類型,主要有兩個作用
復用塊變量類型,使用塊變量類型可以重復定義多個塊變量
使用塊變量類型定義函數參數,這樣可定義帶塊參數的函數
typedef 塊返回值類型(^塊變量類型)(形參類型1,形參類型2,....);
定義一個函數,Block作為函數最後一個參數
typedef NSString* (^LogStr)(NSString *);
void NSLogStr(NSString *name,LogStr log)
{
NSLog(@"%@%@",log(name),@",歡迎您");
}
調用:
NSString *name=@"喬布斯";
NSLogStr(name, ^NSString *(NSString *name) {
return name;
});