美文网首页iOS技巧汇总
iOS Block 内存管理,__block修饰变量值的原理(为

iOS Block 内存管理,__block修饰变量值的原理(为

作者: 孙掌门 | 来源:发表于2019-12-16 20:52 被阅读0次

    Block 内存管理,__block修饰变量值的原理(为什么改变值要用__Block 修饰)

    根据上篇文章,将文件编译为 cpp 文件,通过查看 block 的结构体

    struct __block__testBlock_block_impl_0 {
      struct __block_impl impl;
      struct __block__testBlock_block_desc_0* Desc;
      int i;
      __unsafe_unretained id unsafe_obj;
      __strong id strong_obj;
      int *static_int;
      __block__testBlock_block_impl_0(void *fp, struct __block__testBlock_block_desc_0 *desc, int _i, __unsafe_unretained id _unsafe_obj, __strong id _strong_obj, int *_static_int, int flags=0) : i(_i), unsafe_obj(_unsafe_obj), strong_obj(_strong_obj), static_int(_static_int) {
        impl.isa = &_NSConcreteStackBlock;
        impl.Flags = flags;
        impl.FuncPtr = fp;
        Desc = desc;
      }
    };
    
    

    impl.isa = &_NSConcreteStackBlock;用来标识是哪种类型的 block

    三种 block 类型

    1. _NSConcreteGlobalBlock // 全局block
    2. _NSConcreteStackBlock // 栈block
    3. _NSConcreteMallocBlock // 堆 block
    
    

    block 的 copy 操作,修改值的原理,__forwarding 作用

    --- --- ---
    block类别 原位置 copy之后结果
    _NSConcreteStackBlock
    _NSConcreteGlobalBlock 数据区 不做任何事情
    _NSConcreteMallocBlock 增加引用计数

    栈block在作用于结束之后,对应的block也会销毁

    当在栈上对block进行copy之后,会在堆上copy一份,当栈上变量作用于结束之后,栈block 会销毁,但是堆上会存在。

    所以在mrc对blockcopy之后,容易造成内存泄漏,因为堆上没有释放.

    我们的栈上 block 有一个 __Block 变量,同时还有个__forwarding 指针,指向他自己,当进行copy之后,会在堆上也有一份,同时也会有, __Block变量和 __forwarding 指针,这里面的__forwarding指针的用途是什么呢?当进行copy之后,栈上的__forwarding指针指向堆上的 __Block变量,而堆上的__forwarding指针,也指向自身的
    __Block变量,所以当我们要修改一个值得时候用 __Block指针来修饰,原因是,这时候已经将 栈上面的block,copy 到了堆上面,当我们修改变量的值得时候,其实就是通过栈上面的那个__forwarding指针找到堆上面的__block变量,然后修改堆上面的__Block修饰的变量的值,如果我们这个block被成员变量或者其他地方持有的话,那么实际上就是通过堆上面自身的变量的值,所以可以总结,当我们的栈block经过copy之后,堆上面会有一份,都是通过 __forwarding指针,找到__block变量,然后修改他的值。

    相关文章

      网友评论

        本文标题:iOS Block 内存管理,__block修饰变量值的原理(为

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