block对外部变量的管理之探索

数据类型如下

  • 局部变量
  • 静态变量
  • 全局变量
  • blcok变量

下面是code

局部变量

//局部变量
- (void)testLocalData {
    int temp = 10;
    NSLog(@"outside temp --- >%p", &temp);
    int (^sum)(int,int) = ^(int a, int b) {
        NSLog(@"inside temp --- >%p", &temp);
        return temp + a +b;
    };
    temp = 0;
    int c = sum(1,2);
    NSLog(@"last c --- >%d",c);
    
}

打印结果

2017-12-27 15:56:52.405071+0800 ManagerBlockMemory[7031:472834] outside temp --- >0x7ffee6bceb2c
2017-12-27 15:56:56.002926+0800 ManagerBlockMemory[7031:472834] inside temp --- >0x600000447010
2017-12-27 15:57:04.070374+0800 ManagerBlockMemory[7031:472834] last c --- >13
(lldb) 

静态常量

//静态变量
- (void)testStaticData {
    static int staticTemp = 10;
    NSLog(@"outside staticTemp --- >%p", &staticTemp);
    int (^sum)(int,int) = ^(int a, int b) {
        NSLog(@"inside staticTemp --- >%p", &staticTemp);
        return staticTemp + a +b;
    };
    staticTemp = 0;
    int c = sum(1,2);
    NSLog(@"last staticTest c --- >%d",c);
}

打印结果

2017-12-27 15:59:32.602313+0800 ManagerBlockMemory[7031:472834] outside staticTemp --- >0x109031020
2017-12-27 15:59:34.118012+0800 ManagerBlockMemory[7031:472834] inside staticTemp --- >0x109031020
2017-12-27 15:59:35.782439+0800 ManagerBlockMemory[7031:472834] last staticTest c --- >3

全局变量

//全局变量
- (void)testGlobalData {
    NSLog(@"globalData---->%p",&globalTestData);
    int (^sum)(int,int) = ^(int a, int b) {
        NSLog(@"globalData---->%p",&globalTestData);
        return globalTestData + a + b;
    };
    globalTestData = 0;
    int c = sum(1,2);
    NSLog(@"globalData --%d",c);
}

打印结果

2017-12-27 16:02:58.856153+0800 ManagerBlockMemory[7031:472834] globalData---->0x7fa304e1c710
2017-12-27 16:03:02.124012+0800 ManagerBlockMemory[7031:472834] globalData---->0x7fa304e1c710
2017-12-27 16:03:04.211810+0800 ManagerBlockMemory[7031:472834] globalData --3

block变量

//blcok变量
- (void)testBlockData {
    __block int blockData = 10;
    NSLog(@"blockData-- %p",&blockData);
    int (^sum) (int, int) = ^ (int a, int b){
        NSLog(@"blockData-- %p",&blockData);
        return blockData + a + b;
    };
    blockData = 0;
    int c = sum(1,2);
    NSLog(@"blk test c --- %d",c);
}

打印结果

2017-12-27 16:04:24.820931+0800 ManagerBlockMemory[7031:472834] blockData-- 0x7ffee6bceb28
2017-12-27 16:04:27.759598+0800 ManagerBlockMemory[7031:472834] blockData-- 0x604000628078
2017-12-27 16:04:30.801036+0800 ManagerBlockMemory[7031:472834] blk test c --- 3

上面的4个案列中,分别是对block中遇到的局部变量,静态常量,全局变量和block变量的测试。

可以看到,全局变量 和 静态变量类型时,变量的地址没有变化,由于全局变量和静态变量的内存地址是固定的,block在定义变量的时候,是直接读取的内存地址,没有复制变量值。

再来看本地变量和block变量,在block中内存地址是改变的,但是在方法sum()中,得到的结果却不一样。
对于局部变量,block在定义的时候复制了它,没有复制变量的内存地址,它在block中是作为常量使用的,是不能被修改的,其值不受外面的影响,

对于block变量,可以看到其地址发生了变化,但是blockData却受到外界影响。这是因为,blockData在定义变量本身的时候是位于stack(栈)上的,而在定义block的时候,该变量并不是被复制了一份,而是编译器将其转移到了heap(堆)上,下面是测试代码

- (void)testBlockData {
    __block int blockData = 10;
    NSLog(@"blockData-- %p",&blockData);
    int (^sum) (int, int) = ^ (int a, int b){
        NSLog(@"blockData-- %p",&blockData);
        return blockData + a + b;
    };
    NSLog(@"blockData-- %p",&blockData);
    blockData = 0;
    int c = sum(1,2);
    NSLog(@"blk test c --- %d",c);
}

下面是输出

2017-12-27 16:40:30.971155+0800 ManagerBlockMemory[7445:512216] blockData-- 0x7ffeef5d7b28
2017-12-27 16:40:30.971420+0800 ManagerBlockMemory[7445:512216] blockData-- 0x60000003f458
2017-12-27 16:40:35.657576+0800 ManagerBlockMemory[7445:512216] blockData-- 0x60000003f458
2017-12-27 16:40:38.758031+0800 ManagerBlockMemory[7445:512216] blk test c --- 3
总结一下:

局部变量是以值传递的方式传递到block里。block值捕获block中会用到的变量,由于只捕获了局部变量的值,非内存地址,多以block内部不能修改局部变量的值。

Block捕获的外部变量可以改变值的是静态变量,block变量,全局变量.

有的博客写到,在Block中改变变量值有2种方式,
一是传递内存地址指针到Block中,
二是改变存储区方式(__block)
第二种要好好研究下

参考博客:

深入研究Block捕获外部变量和__block实现原理

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容