美文网首页
Block内存问题

Block内存问题

作者: 爆炸的白菜君 | 来源:发表于2017-03-09 23:31 被阅读11次
      int a = 10;
      void(^block)() = ^{
            a=20;
      };
      block();
    

    这种写法会报错,因为在block中使用的a相当于是一个常亮10,在runtime语句中是将a作为一个常亮在传递就是10,这样就讲得通为什么会报错。因为10不可能被赋值成20

    __block int a = 10;
    void(^block)() = ^{
        a=20;
    };
    block();
    

    这种写法就是正确的写法,因为Runtime中是将block中的a作为一个指针在传递,对一个指针是可以做赋值操作的,拿到a的地址将里面的内容修改成20.

    内存管理

    block是存在一栈中的

    __block int a = 10;
    void(^block)() = ^{
     a=20;
     };
    block();
    

    对block进行copy操作之后就会把block拷贝到堆内存中(MRC写法)

    __block int a = 10;
    void(^block)() = ^{
      a=20;
    };
    Block_copy(block);
    block();
    

    为什么要对Block进行copy操作呢?
    因为如果不对Block进行Copy操作的话block会在栈区,栈区的内存不受开发者管理,所以很容易就被释放掉,不稳定。copy到堆区以后就,block的释放就完全受制于开发者,所以要对block进行copy操作。

    Block的循环引用问题

    Dog *dog = [[Dog alloc] init];      
     dog.block = ^(){
       [dog run];
    };
    
    

    这段代码就出现了循环引用。
    dog对象持有block,block中也持有dog对象
    解决办法

    MRC

    __block Dog *dog = [[Dog alloc] init];
    dog.block = ^(){
        [dog run];
    };
    

    __block修饰以后就告诉block不要对这个对象持有(做retain操作)

    ARC

    __weak Dog *dog = [[Dog alloc] init];
     dog.block = ^(){
       [dog run];
    };
    
    __unsafe_unretained Dog *dog = [[Dog alloc] init];
    dog.block = ^(){
       [dog run];
     };
    

    相关文章

      网友评论

          本文标题:Block内存问题

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