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一下
typedef void (^BoolBlock)(BOOL);//一個只接受一個BOOL參數,沒有返回值的block typedef int (^IntBlock)(void);//一個沒有參數,返回int的block typedef BoolBlock (^HugeBlock)(IntBlock);//看看,這個HugeBlock的參數和返回值都是block
三、更詳細的例子
注意:上面的typedef都還有效~
主動調用一下:
- (void)someMethod { BoolBlock ablock = ^(BOOL bValue) { NSLog(@"Bool block!"); }; ablock(); }
作爲參數返回:
typedef void (^BoolBlock)(BOOL); - (BoolBlock)foo() { BoolBlock ablock = ^(BOOL bValue) { NSLog(@"Bool block!"); }; return [[ablock copy] autorelease];//一定要copy,將其複製到堆上,更詳細的原理,將在後續章節講解 }
類的一個成員:
@interface OBJ1 : NSObject @property (nonatomic, copy)BoolBlock block;//理由同上啊,同學們 @end OBJ1 *obj1 = ... obj1.block = ^(BOOL bValue) { NSLog(@"Bool block!"); };
其他函數的參數:
- (void)foo(BoolBlock block) { if (block) { block(); } }
甚至其他block的參數:
BoolBlock bBlock = ^(BOOL bV){if(Bv){/*do some thing*/}}; HugeBlock hBlock = ^(BoolBlock bB) {bB();}; hBolck(bBlock);
啊,全局變量!:
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標記,是無法通過編譯的。 } }; }
好了,基礎很快,更詳細的內容將用來介紹深入的東西。