block 的數據結構定義以下(圖片來自 這裏):數據結構
對應的結構體定義以下:ide
struct Block_descriptor { unsigned long int reserved; unsigned long int size; void (*copy)(void *dst, void *src); void (*dispose)(void *); }; struct Block_layout { void *isa; int flags; int reserved; void (*invoke)(void *, ...); struct Block_descriptor *descriptor; /* Imported variables. */}; |
|
isa 指針,全部對象都有該指針,用於實現對象相關的功能。函數
flags,用於按 bit 位表示一些 block 的附加信息,本文後面介紹 block copy 的實現代碼能夠看到對該變量的使用。spa
reserved,保留變量。指針
invoke,函數指針,指向具體的 block 實現的函數調用地址。code
descriptor, 表示該 block 的附加描述信息,主要是 size 大小,以及 copy 和 dispose 函數的指針。orm
variables,capture 過來的變量,block 可以訪問它外部的局部變量,就是由於將這些變量(或變量的地址)複製到告終構體中。對象
該數據結構和後面的 clang 分析出來的結構實際是同樣的,不過僅是結構體的嵌套方式不同。但這一點我一開始沒有想明白,因此也給你們解釋一下,以下 2 個結構體 SampleA 和 SampleB 在內存上是徹底同樣的,緣由是結構體自己並不帶有任何額外的附加信息。圖片
struct SampleA { int a; int b; int c; }; struct SampleB { int a; struct Part1 { int b; }; struct Part2 { int c; }; }; |
在 Objective-C 語言中,一共有 3 種類型的 block:ip
_NSConcreteGlobalBlock 全局的靜態 block,不會訪問任何外部變量。
_NSConcreteStackBlock 保存在棧中的 block,當函數返回時會被銷燬。
_NSConcreteMallocBlock 保存在堆中的 block,當引用計數爲 0 時會被銷燬。