i一、概述
Block語法
原理:把一個方法體 整體作爲一個指針對象
語法:
返回值(^塊名稱)(參數類型 參數名,參數類型 參數名....) typedef <#returnType#>(^<#name#>)(<#arguments#>);
例如: void(^BlockName)(int a,NSString *str) typedef void(^ShowTextBlock)(NSString *text);
塊語法的消息回傳原理是:
把第一頁的一個方法 作爲 參數傳遞給第二頁,第二頁 可以調用它 並傳入第二頁的參數 step1.在第二頁聲明塊
step2.在第二頁頭文件聲明 塊 類型的對象,用於接收傳參
step3.在第二頁的.m文件中 適當的位置調用塊方法
—————————————————————————————————
step4.在第一頁中,向第二頁傳遞 塊方法
Block是C級別的語法和運行時特性。Block比較類似C函數,但是Block比之C函數,其靈活性體現在棧內存、堆內存的引用,我們甚至可以將一個Block作爲參數傳給其他的函數或者Block。
二、熱身
先看一個比較簡單的Block例子:
- int multiplier = 7;
- int (^myBlock)(int) = ^(int num) {
- return num * multiplier;
- };
在這個例子中,myBlock是一個Block變量,它接受一個int類型的參數,返回一個int類型的值。是不是很像C函數?
來,讓我們typedef一下
void (^myBlock1)(void); //無返回值,無參數
void (^myBlock2)(NSObject, int); //有返回值,有參數
NSString* (^myBlock3)(NSString* name, int age); //有返回值和參數,並且在參數類型後面加入了參數名(僅爲可讀性)
- typedef void (^BoolBlock)(BOOL);//一個只接受一個BOOL參數,沒有返回值的block
- typedef int (^IntBlock)(void);//一個沒有參數,返回int的block
- typedef BoolBlock (^HugeBlock)(IntBlock);//看看,這個HugeBlock的參數和返回值都是block
三、更詳細的例子
注意:上面的typedef都還有效~
(1)主動調用一下:
- - (void)someMethod
- {
- BoolBlock ablock = ^(BOOL bValue) {
- NSLog(@"Bool block!");
- };
- ablock();
- }
(2)作爲參數返回:
- typedef void (^BoolBlock)(BOOL);
- - (BoolBlock)foo()
- {
- BoolBlock ablock = ^(BOOL bValue) {
- NSLog(@"Bool block!");
- };
- return [[ablock copy] autorelease];//一定要copy,將其複製到堆上,更詳細的原理,將在後續章節講解
- }
(3)類的一個成員:
- @interface OBJ1 : NSObject
- @property (nonatomic, copy)BoolBlock block;//理由同上啊,同學們
- @end
- OBJ1 *obj1 = ...
- obj1.block = ^(BOOL bValue) {
- NSLog(@"Bool block!");
- };
(3)其他函數的參數:
- - (void)foo(BoolBlock block)
- {
- if (block) {
- block();
- }
- }
(5)甚至其他block的參數:
- BoolBlock bBlock = ^(BOOL bV){if(Bv){/*do some thing*/}};
- HugeBlock hBlock = ^(BoolBlock bB) {bB();};
- hBolck(bBlock);
(5)啊,全局變量!:
- static int(^maxIntBlock)(int, int) = ^(int a, int b){return a>b?a:b;};
- int main()
- {
- printf("%d\n", maxIntBlock(2,10));
- return 0;
- }
好了,你知道block大概能怎麼用了。
四,特殊的標記,__block
如果要在block內修改block外聲明的棧變量,那麼一定要對該變量加__block標記:
- int main()
- {
- __block int i = 1024;
- BoolBlock bBlock = ^(BOOL bV) {
- if (bV) {
- i++;//如果沒有__block標記,是無法通過編譯的。
- }
- };
- }