Block 在 Objective-C 中也是被當成對象的, Block 有三種類。
類 | 設置對象的存儲區域 |
---|---|
_NSConcreteStackBlock | 棧 |
_NSConcreteClobalBlock | 程序的數據區域(.data 區) |
_NSConcreteMallocBlock | 堆 |
void(^globalBlock)(void) = ^{
NSLog(@"globalBlock");
};
NSLog(@"%@", globalBlock); //<__NSGlobalBlock__: 0x105f6b0c0>
在沒有捕獲任何自動變量的時候, Block 的類型為NSGlobalBlock
.
int a = 0;
void(^stacklBlock)(void) = ^{
NSLog(@"stacklBlock, a = %d", a);
};
NSLog(@"%@", stacklBlock);//<__NSStackBlock__: 0x7fff59c94ac0>
捕獲自動變量的時候, Block 的類型為NSStackBlock
.
void(^mallocBlock)(void) = [stacklBlock copy];
NSLog(@"%@", mallocBlock);//<__NSMallocBlock__: 0x7fced2e8d240>
對 Block 在堆上進行復制的時候, 復制后的類型為NSMallocBlock
.
將 Block 作為函數的返回值時, 編譯器會自動生成復制到堆上的代碼. Blocks 從棧上復制到堆中, 這樣即使 Block 的變量作用域結束, 堆上的 Block 還可以繼續存在.
在ARC開啟的情況下,將只會有NSConcreteGlobalBlock
和 NSConcreteMallocBlock
類型的block。原本的NSConcreteStackBlock
的block會被NSConcreteMallocBlock
類型的block替代。