iOS Block在内存中的位置及内存管理

一、关于block在内存的位置

Block在内存中的位置分三种:
1、NSGlobalBlock:类似函数,位于代码段(未引用外部变量):

float (^sum)(float, float) = ^(float a, float b){



    return a + b;

};

2、NSStackBlock:位于栈内存,函数返回后block将无效(引用外部变量,但只能在该函数作用域内使用,出作用域该变量内存已被释放,出作用域触发block访问该变量会Crash):

{

NSArray *testArr = @[@"1", @"2"];



void (^TestBlock)(void) = ^{



    NSLog(@"testArr :%@", testArr);

};



NSLog(@"block is %@", ^{



    NSLog(@"test Arr :%@", testArr);

});
}

3、NSMallocBlock:位于堆内存(对NSStackBlock 使用copy修饰(strong 应该也可以))该类型拥有保存外部变量内存的能力。所以调用外部变量不会crash,下面将讲解对外部变量的存取管理。

二、关于block外部变量的存取管理

#######在这里只讨论ARC机制下

- (void)test

{
int a = 0;
__block int  b = 0;
self.globstring = @"1";
NSString *__localString = @"1";
__block NSString *_blockString = @"1";
printf("a address: %p\n", &a); //a address: 0x7fff56516b3c

printf("b address: %p\n", &b); //b address: 0x7fff56516b30

printf("local address: %p\n", &__localString); //local address: 0x7fff56516b00
printf("_block address: %p\n", &_blockString); //_block address: 0x7fff56516af8
printf("glob address: %p\n", &_globstring); //glob address: 0x7fed5bc09520

void (^TestBlock)(void) = ^{
    printf("a value: %d\n", a); //a value: 0
    printf("b value: %d\n", b); //b value: 1
    printf("b address: %p\n", &b); //b address: 0x60800002a7f8
    
    printf("local address: %p\n", &__localString); //       local address: 0x6080000979a0
    NSLog(@"lockstring is : %@\n", __localString); //lockstring is : 1
    
    printf("_blcok address: %p\n", &_blockString); //_blcok address: 0x6080000470d8
    NSLog(@"_blcokstring is : %@\n", _blockString); //_blcokstring is : 2

    printf("globaddress: %p\n", &_globstring); //globaddress: 0x7fed5bc09520
    NSLog(@"globstring is : %@\n", _globstring); //globstring is : 2
    
};
 __weak typeof(self) this = self;
self.copyBlock = ^{
    printf("a value: %d\n", a); //a value: 0
    printf("b value: %d\n", b); // b value: 1
    printf("b address: %p\n", &b); // b address: 0x60800002a7f8
    printf("copy block local address: %p\n", &__localString); //copy block local address: 0x608000099660
    
    NSLog(@"copy block string is : %@\n", __localString); //copy block string is : 1
    
    printf("_blcok address: %p\n", &_blockString); //_blcok address: 0x6080000470d8
    
    NSLog(@"_blcokstring is : %@\n", _blockString); //_blcokstring is : 2
    
    printf("glob address: %p\n", &_globstring); //glob address: 0x7fed5bc09520
    
    NSLog(@"string is : %@\n", this.globstring); //string is : 2

};
a = 1;
b = 1;
printf("a address: %p\n", &a); //local address: 0x7fff56516b3c
printf("b address: %p\n", &b); //_block address: 0x60800002a7f8

printf("local address: %p\n", &__localString); //local address:  0x7fff56516b00
printf("_block address: %p\n", &_blockString); //_block address: 0x60800002a7f8

__localString = nil;
_blockString = @"2";
self.globstring = @"2";

TestBlock();
self.copyBlock();
}

通过观察上面的输出,得出结论 :
1、普通的局部变量,BLOCK声明时会COPY它的值,并且拥有新的地址,也就是说block内部a 地址和外部a地址不同(如上)。互不影响。
2、__block局部变量,BLOCK声明时会在堆中新建一个内存地址,并且BLOCK之后的所有b 或者 _blockString (如上)都是这个地址,所以后续的读写都是再这个地址上进行。会不想影响。即使不触发block 地址也已经不是原来的地址。
3、全局变量 globstring (如上)BLOCK 访问都是 它本身的地址。直接读写操作。
4、BLOCK引用外部对象时会强引用外部变量 ,如果该外部变量也强引用BLOCK就会造成return circle (比如self property block ,block 内部访问self 或者self的属性),为了解决这个使用weakSelf。

以上均为测试并发表的自己的见解,只能模糊的用自己的语言描述。对于内存管理一直都是一知半解。网上看的BLOCK的结构看的不是很懂。只能通过实验的方式看地址的变化。希望大家有见解都写在评论里 帮助我加深理解,比如有文章说是__block 变量地址在BLOCK申明后地址是怎么发生改变的?希望大家多多关照。共同进步!
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容