iOS 的三种block
block有三种:
NSStackBlock存储于栈区
NSGlobalBlock存储于程序数据区
NSMallocBlock存储于堆区
NSGlobalBlock 静态区block,这是一种特殊的bloclk,因为不引用外部变量而存在。另外,作为静态区的对象,它的释放是有操作系统控制的,这一点我们最后再聊。
NSStackBlock 栈区block,位于内存的栈区,一般作为函数的参数出现。
NSMallocBlock 堆区block,位于内存的堆区,一般作为对象的property出现。
如果一个blcok引用了外部变量是栈block,则其不引用外部变量就成为了静态blcok。
如果一个block引用了外部变量是堆block,则其不引用外部变量就成为了静态block。
MRC 下
@property(nonatomic,copy)void(^block)();
int value =10;
void(^blockA)() = ^ {
NSLog(@"value: %d",value);
};
NSLog(@"MRC 引用计数: %ld, block is: %@",[blockA retainCount], blockA);
void(^blockB)() = ^{
NSLog(@"blockB");
};
NSLog(@"MRC 引用计数: %ld, block is: %@",[blockB retainCount], blockB);
_block = [blockA copy];
NSLog(@"MRC 引用计数: %ld, block is: %@",[self.block retainCount],self.block); [_block retain];
NSLog(@"MRC 引用计数: %ld, block is: %@",[self.block retainCount],self.block); [_block release];
NSLog(@"MRC 引用计数: %ld, block is: %@",[self.block retainCount],self.block);
打印结果:
MRC 引用计数:1, blockis: <__NSStackBlock__:0x7fff59038bc8>
MRC 引用计数:1, blockis: <__NSGlobalBlock__:0x106bc70e0>
MRC 引用计数:1, blockis: <__NSMallocBlock__:0x610000058330>
MRC 引用计数:1, blockis: <__NSMallocBlock__:0x610000058330>
MRC 引用计数:1, blockis: <__NSMallocBlock__:0x610000058330>
可以看到,blockA 与 blockB 的差异只在于有没有调用外部变量,这点差异导致它们的类型不同,存储位置不同。