摘自:函數
《Effcitive Objective-C 2.0 編寫高質量iOS與OS X代碼的52個有效方法》atom
第37條:理解「塊」這一律念spa
Block (塊)指針
塊類型的語法結構以下:code
return_type (^block_name) (parameters)對象
______________________________________________________________________________________blog
在BDN代碼裏看到一句:ci
typedef void(^BDNCouponQueryViewControllerQueryCompletion)(BDNBaseViewController *viewController);it
這句話的意思是,定義了一個block:io
block名爲BDNCouponQueryViewControllerQueryCompletion
參數是BDNBaseViewController對象
返回爲void
使用方法:
@property (nonatomic, copy) BDNCouponQueryViewControllerQueryCompletion queryCompletion;
能夠看到這個block,能夠做爲類型來定義新的對象
______________________________________________________________________________________
e.g.
定義一個加法block,輸入兩個int,輸出一個int
定義:
int (^addBlock) (int a, int b) = ^(int a, int b){ return a + b; };
注意:最後有個分號,應爲這只是一個定義語句,而不是一個方法塊
使用:
int add = addBlock(2, 3);
能夠看出,長得很像函數指針。
塊能夠捕獲其聲明範圍內的全部變量
默認狀況下,爲塊捕獲的變量,是不可在塊中修改的
但若是在聲明變量前加上__block修飾符,就能夠在塊內修改
內聯塊
e.g.
NSArray *array = @[@0, @1, @2, @3, @4, @5]; __block NSInteger count = 0; [array enumerateObjectsUsingBlock:^(NSNumber *number, NSUInteger idx, BOOL *stop) { if ([number compare:@2] == NSOrderedAscending) { count ++; } }]; NSLog(@"%ld", (long)count);
所謂內聯塊,指的是,如上所示,傳給 enumerateObjectsUsingBlock: 方法的塊以前並未先賦值給局部變量,而是直接內聯在函數調用裏面。
若是塊捕獲的變量是對象類型,則會自動保留
塊同其它對象同樣,有引用計數
當最後一個指向塊的引用移走後,塊就回收了
回收的同時也會釋放塊所捕獲的變量,以便平衡捕獲時所執行的保留操做