美文网首页
block 内存管理

block 内存管理

作者: Berning | 来源:发表于2021-06-17 01:53 被阅读0次

block修改变量

  • 示例代码
        void (^block)(void);
        
        {
            __block int a = 10;
            block = ^{
                 a = 20;
                 NSLog(@"person-%d",a);
             };
            
        }
        
        block();
    }
    
  • __block 会把变量包装成一个结构体
struct __Block_byref_a_0 {
  void *__isa;
__Block_byref_a_0 *__forwarding;
 int __flags;
 int __size;
 int a;
};

  • block
struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  __Block_byref_a_0 *a; // by ref
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __Block_byref_a_0 *_a, int flags=0) : a(_a->__forwarding) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

  • block 代码块/内存管理/调用环境描述
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
  __Block_byref_a_0 *a = __cself->a; // bound by ref

                 (a->__forwarding->a) = 20;
                 NSLog((NSString *)&__NSConstantStringImpl__var_folders_p8_kz1xzn596q746q_0rv80p9zc0000gn_T_main_e0776a_mi_0,(a->__forwarding->a));
             }
static void __main_block_copy_0(struct __main_block_impl_0*dst, struct __main_block_impl_0*src) {_Block_object_assign((void*)&dst->a, (void*)src->a, 8/*BLOCK_FIELD_IS_BYREF*/);}

static void __main_block_dispose_0(struct __main_block_impl_0*src) {_Block_object_dispose((void*)src->a, 8/*BLOCK_FIELD_IS_BYREF*/);}

static struct __main_block_desc_0 {
  size_t reserved;
  size_t Block_size;
  void (*copy)(struct __main_block_impl_0*, struct __main_block_impl_0*);
  void (*dispose)(struct __main_block_impl_0*);
} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0), __main_block_copy_0, __main_block_dispose_0};

  • block使用
        void (*block)(void);

        {

            __attribute__((__blocks__(byref))) __Block_byref_a_0 a = {(void*)0,(__Block_byref_a_0 *)&a, 0, sizeof(__Block_byref_a_0), 10};
            block = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, (__Block_byref_a_0 *)&a, 570425344));

        }

        ((void (*)(__block_impl *))((__block_impl *)block)->FuncPtr)((__block_impl *)block);

对象类型的auto变量和 __block变量

  • __NSStackBlock__ 都不会强引用
  • __NSMallocBlock__block从栈拷贝到堆上时,调用copy方法,copy方法调用_Block_object_assign
    1>_Block_object_assign根据__对象类型的auto变量是__strong/__weak,决定强/弱引用 (3/BLOCK_FIELD_IS_OBJECT/)
    2> _Block_object_assign对__block变量强引用(8/BLOCK_FIELD_IS_BYREF/)

__block修饰对象

  • 会把对象包装成__Block_byref_person_0结构体,并对对象进行内存管理
struct __Block_byref_person_0 {
  void *__isa;
__Block_byref_person_0 *__forwarding;
 int __flags;
 int __size;
 void (*__Block_byref_id_object_copy)(void*, void*);
 void (*__Block_byref_id_object_dispose)(void*);
 NSPerson *__strong person;
};

  • block内引用__Block_byref_person_0类型的结构体对象
struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  __Block_byref_person_0 *person; // by ref
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __Block_byref_person_0 *_person, int flags=0) : person(_person->__forwarding) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

  • __main_block_desc_0里面对__Block_byref_person_0进行内存管理
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
  __Block_byref_person_0 *person = __cself->person; // bound by ref


                 NSLog((NSString *)&__NSConstantStringImpl__var_folders_p8_kz1xzn596q746q_0rv80p9zc0000gn_T_main_4e2f7c_mi_0,(person->__forwarding->person));
             }
static void __main_block_copy_0(struct __main_block_impl_0*dst, struct __main_block_impl_0*src) {_Block_object_assign((void*)&dst->person, (void*)src->person, 8/*BLOCK_FIELD_IS_BYREF*/);}

static void __main_block_dispose_0(struct __main_block_impl_0*src) {_Block_object_dispose((void*)src->person, 8/*BLOCK_FIELD_IS_BYREF*/);}

static struct __main_block_desc_0 {
  size_t reserved;
  size_t Block_size;
  void (*copy)(struct __main_block_impl_0*, struct __main_block_impl_0*);
  void (*dispose)(struct __main_block_impl_0*);
} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0), __main_block_copy_0, __main_block_dispose_0};

  • 创建__Block_byref_person_0时会创建一个对象传给__Block_byref_person_0,并调用__Block_byref_id_object_copy_131,__Block_byref_id_object_dispose_131对对象进行内存管理
int main(int argc, const char * argv[]) {
    /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 


        void (*block)(void);

        {
            __attribute__((__blocks__(byref))) __Block_byref_person_0 person = {
          (void*)0,
          (__Block_byref_person_0 *)&person, 
          33554432,
          sizeof(__Block_byref_person_0), 
          __Block_byref_id_object_copy_131,
         __Block_byref_id_object_dispose_131,
         ((NSPerson *(*)(id, SEL))(void *)objc_msgSend)((id)((NSPerson *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("NSPerson"), sel_registerName("alloc")), sel_registerName("init"))};



            block = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, (__Block_byref_person_0 *)&person, 570425344));

        }

        ((void (*)(__block_impl *))((__block_impl *)block)->FuncPtr)((__block_impl *)block);
    }


    NSLog((NSString *)&__NSConstantStringImpl__var_folders_p8_kz1xzn596q746q_0rv80p9zc0000gn_T_main_4e2f7c_mi_1);

    return 0;
}

  • __Block_byref_person_0对对象进行内存管理
static void __Block_byref_id_object_copy_131(void *dst, void *src) {
_Block_object_assign((char*)dst + 40, *(void * *) ((char*)src + 40), 131);
}
static void __Block_byref_id_object_dispose_131(void *src) {
_Block_object_dispose(*(void * *) ((char*)src + 40), 131);
}
  • 上面+40是指向了 NSPerson *__strong person;
struct __Block_byref_person_0 {
  void *__isa;      //8
__Block_byref_person_0 *__forwarding;  //8
 int __flags;      //4
 int __size;      //4
 void (*__Block_byref_id_object_copy)(void*, void*);  //8
 void (*__Block_byref_id_object_dispose)(void*);    //8
 NSPerson *__strong person;
};

MRC环境__block修饰对象都是弱引用

相关文章

  • Block内存管理实例分析

    Block内存管理实例分析 Block内存管理实例分析

  • Block内存管理

    对block自身内存的管理 对于block,有两个内存管理方法:Block_copy, Block_release...

  • iOS内存管理详解

    目录 block内存管理 autorelease内存管理 weak对象内存管理 NSString内存管理 new、...

  • Block 使用总结

    Block 内存管理: Block 内存主要分派到 NSGlobalBlock(data area),NSMall...

  • iOS面试之Block大全

    Block Block内容如下: 关于Block 截获变量 __block修饰符 Block的内存管理 Block...

  • iOS面试之Block模块

    Block Block内容如下: 关于Block 截获变量 __block修饰符 Block的内存管理 Block...

  • Block

    一、Block本质 二、 BlocK截获变量 三、__block 修饰变量 四、Block内存管理 五、Block...

  • Block

    Block介绍 截获变量 __block修饰符 Block的内存管理 Block的循环引用 一、Block介绍 1...

  • block的内存管理

    block的内存默认放在栈中,(开发人员不需要管理block内存),block所引用的对象的retainCount...

  • block的一些注意事项

    Block的使用注意: block的内存管理(注意循环引用,默认在栈中(不需要内存管理),通过copy就在在堆中,...

网友评论

      本文标题:block 内存管理

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