Block 語法:
作為當地變量:?
?returnType (^blockName)(parameterTypes) = ^returnType(parameters) { ... ... }
作為屬性: ?
@property (nonatomic,copy) returnType (^blockName)(parameterTypes)
作為方法參數:
??-(void)someMethodThatTakesABlock:( returnType (^)(parameterTypes) )blockName
作為方法調用的參數:
[someObject someMethodThatTakesABlock:^returnType(parameters){ ... ... } ];
作為typeDef:
typedef returnType(^typeName)(parameterTypes)
TypeName blockName = ^returnType(parameters) { ... ... };
Block算是一個對象
BLock對變量的捕獲規則
1 靜態存儲區的變量,例如全局變量,方法中的static變量,
可引用可修改
2 block接受的參數
傳值,可修改,和一般函數的參數相同
3 棧變量:(被捕獲的上下文變量)
const,不可修改,當block被copy后,block會對ID類型的變量產生弱引用,每次執行block 時捕獲到的變量都是最初的值
4 棧變量(有block 前綴)
引用,可修改。如果是id類型則不會被block ?retain, 必須手動處理其內存管理
如果是C類型變量,blcok 被copy到heap后,改值也會被挪動到heap
內存:
Block_copy()和Block_release()必須匹配
_block修飾詞會將原本簡單類型轉化為較大的struct,給內存調用帶來額外的開銷
循環引用:block 被copy之后,該block會對他捕獲到的對象產生Strong引用,如果self引用的block,block捕獲了self,將會造成內存循環,解決方法
如果捕獲到的是當前變量的成員變量,也會造成對self 的引用,同樣會造成內存循環
Block是個對象,他對他所捕獲到的值都進行強引用(strong)