美文网首页
block对外部变量的管理之探索

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

作者: 骨古 | 来源:发表于2017-12-27 16:52 被阅读27次

数据类型如下

  • 局部变量
  • 静态变量
  • 全局变量
  • 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对外部变量的管理之探索

    数据类型如下 局部变量 静态变量 全局变量 blcok变量 下面是code 局部变量 打印结果 静态常量 打印结果...

  • __block的实现和内存管理

    __block的内存管理 当block使用外部变量时,是不能直接在block内修改这些变量的。我们用__block...

  • iOS Block 部分三

    主要讲解 Block内修改外部变量, 内存管理, 以及循环引用; Block部分一Block部分二Block部分三...

  • block

    block block内部访问外部的变量 如果外部的变量是基本数据类型,在block内部不可以直接修改外部变量的值...

  • iOS面试题(31.Block的循环引用、内部修改外部变量、三种

    block强引用self,self强引用block内部修改外部变量:block不允许修改外部变量的值,这里的外部变...

  • Block

    block的内存管理: 无论当前环境下是arc还是mrc,只要block没有访问外部变量,block始终在全局区 ...

  • Block

    Block Block 可以捕获外部变量 Block 可以捕获来自外部作用域的变量,这是Block一个很强大的特性...

  • Block

    Block block内存管理 无论是MRC还是ARC,只要block没有访问外部变量,blokc始终在全局区 M...

  • OC底层原理探索-block(下)

    本篇文章我们来探索下block的底层原理实现,栈区block是如何拷贝的堆区的,block捕获外部变量的本质,bl...

  • iOS底层原理 - block如何修改外部变量

    在block里面需要修改外部变量时,我们会使用__block修饰这个外部变量,然后再对其进行修改操作,这是为什么呢...

网友评论

      本文标题:block对外部变量的管理之探索

      本文链接:https://www.haomeiwen.com/subject/fmyugxtx.html