@IT·互联网iOS

Objective-C中Block内存分配全解析

2018-09-12  本文已影响20人  ChinaChong

Block的类

设置对象的储存域
_NSConcreteStackBlock 栈区
_NSConcreteGlobalBlock 程序的数据区(全局区)
_NSConcreteMallocBlock 堆区

Block分配的规律

Block不论在ARC下还是在MRC下,都会视情况被分配到这三种区中。我总结了分配在各种区的条件,如下:

Block执行过copy后的情况

Block的类 副本源的配置储存域 复制效果
_NSConcreteStackBlock 栈区 从栈复制到堆
_NSConcreteGlobalBlock 全局区 什么也不做
_NSConcreteMallocBlock 堆区 引用计数增加

栈上的Block什么时候会被复制到堆

接下来就结合代码来分析Block的内存分配。

等号左侧在OC默认情况下属于强指针,用__weak修饰后变成弱指针,右侧Block不会被持有,并且Block引用了外部变量,所以会被分配在栈区

int temp = 10;
__weak void(^blk_t1)(void) = ^{
    NSLog(@"%d",temp);
};
NSLog(@"1===%@",blk_t1);
image.png

等号左侧在OC默认情况下属于强指针,右侧block被持有,引用外部变量就分配在堆区

int temp = 10;
void(^blk_t)(void) = ^{
    NSLog(@"%d",temp);
};
blk_t();
NSLog(@"2===%@",blk_t);
image.png

等号左侧在OC默认情况下属于强指针,右侧block被持有,不引用外部变量就分配在全局区

void(^blk_tt)(void) = ^{
        
};
NSLog(@"3===%@",blk_tt);
image.png

此block未被持有,且引用了外部变量,所以分配在栈区

int temp = 10;
NSLog(@"4===%@",^{
    NSLog(@"%d",temp);
});
image.png

栈区的block在执行copy后会被分配到堆区

int temp = 10;
NSLog(@"5===%@",[^{
    NSLog(@"%d",temp);
} copy]);
image.png

等号左侧在OC默认情况下属于强指针,右侧block被持有,block内部未引用外部变量,被分配到全局区,执行copy后依然在全局区

void (^blk_ttt)(void) = ^() {
    
};
blk_ttt();

NSLog(@"\n6===\n拷贝前%@\n拷贝后%@",blk_ttt,[blk_ttt copy]);
image.png

block使用内部局部变量,未引用外部变量,依然是全局block

void (^blk_tttt)(void) = ^{
    int b = 20;
    NSLog(@"%d",b);
};
blk_tttt();
NSLog(@"7===%@",blk_tttt);
image.png

block内部使用传进来的参数,并不会持有该参数,此block在使用了参数后依然是全局block

NSString *str = @"I love China!";
void (^blk_ttttt)(NSString *) = ^(NSString *param){
    NSLog(@"%@",param);
};
blk_ttttt(str);
NSLog(@"8===%@",blk_ttttt);
image.png
上一篇 下一篇

猜你喜欢

热点阅读