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实现原理

你可能感兴趣的:(block对外部变量的管理之探索)