OC中的Block(四)

__block修饰符的内存管理

  1. 当block在栈上时,并不会对__block变量产生强引用

  2. 当__block修饰指针变量时,会在成的__Block_byref_xxx_0结构体中生成
    从copy函数和dispose函数:

void (*__Block_byref_id_object_copy)(void*, void*);
void (*__Block_byref_id_object_dispose)(void*);

当block被copy到堆时

  • 会调用block内部的copy函数
  • copy函数内部会调用_Block_object_assign函数
  • _Block_object_assign函数会对__block变量形成强引用(retain)
15432991962845.jpg

15432992034437.jpg

当block从堆中移除时

  • 会调用block内部的dispose函数
  • dispose函数内部会调用_Block_object_dispose函数
  • _Block_object_dispose函数会自动释放引用的__block变量(release)
15432992231689.jpg
15432992270179.jpg

示例代码:

__block int lisi_age = 18;
block b = ^{
        NSLog(...);
    };
    b();

生成的__main_block_impl_0结构体

struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  
  __Block_byref_lisi_age_1 *lisi_age; // by ref
}

生成的__main_block_desc_0结构体

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修饰的指针类型变量生成的__Block_byref_lisi_age_1结构体

struct __Block_byref_lisi_age_1 {
  void *__isa;
__Block_byref_lisi_age_1 *__forwarding;
 int __flags;
 int __size;
 int lisi_age;
};
__Block_byref_lisi_age_1 lisi_age = {
    (void*)0,
    (__Block_byref_lisi_age_1 *)&lisi_age,
    0,
    sizeof(__Block_byref_lisi_age_1),
    18  
    };

__block的__forwarding指针

15432998612018.jpg
15432998651329.jpg

你可能感兴趣的:(OC中的Block(四))