block的內存模型
block的內存模型是一個結構體,其中有兩個字段。一個是isa,代表block是一個對象,另外這個對象里面有一個imp,執行block執行的代碼。
id imp_getBlock(IMP anImp);//獲取IMP是anImp的Block。
Bool imp_removeBlock(IMP anImp);//解除block與imp的關聯。
IMP imp_implementationWithBlock ( id block );//獲取block的IMP。
block的幾種寫法
1.聲明一個block變量。--箭頭在中間
returnType (^blockName)(parameterTypes);//定義了一個blockName的block
如 void^myBlock (int);
還可以先定義一個block的類型:
typedef returnType (^BlockType)(parameterTypes);//定義了一個類型為BlockType的block類型。
BlockType myBlock; //定義了一個myBlock變量。
2,給block變量賦值
returnType(^blockName)(parameterTypes) = ^returnType(parameters) {...};
3,block作為形參
- (void) testBlock: returnType(^)(parameterTypes)blockName;
4,block作為返回值
-(returnType(^)(parameterTypes))block{
? ? return returnType(^)(parameterTypes){
? ? ? ? ? //........ ??
? ? ? ? ? ?return returnType;
? ?};
}
block實現鏈式編程
鏈式編程給人一種優雅的感覺,此外,它還給編程帶來一種一致感,便于維護。這種編程風格讓我們更直觀的感受到對對象狀態的操作。
Objective-C是采用[objc method]這種方式來調用方法。要實現objc.method1().method2()....
1.getter方法block,將block聲明為getter方法的樣式就可以使用點語法,重寫block的getter方法,在block里面處理業務邏輯,外界只傳入參數。
2,block返回對象本身。
Block的copy關鍵字
? ? ? ?一般block是在棧區創建的,當函數執行完畢,棧區上的對象就會被釋放。賦值給copy關鍵字修飾的對象的時候,會將block在堆內存中copy一份,避免彈棧導致block被釋放,其他地方引用不到的問題。
Block所在的內存區域。
理論上Block在內存中的存儲位置有三種,棧區(StackBlock),堆區(MallocBlock),全局區(GlobalBlock)。
但是在ARC的環境下,棧區的block會自動copy到堆區,因此,ARC的環境下,Block的內存位置只有堆區和全局區。
其中,如果Block沒有引用外部對象(外部基本類型的變量不算)的話,就存儲在全局區,否則存儲在堆區。