Block 本质-day1

309 阅读1分钟

本文章主要是对block本质的进行探讨和研究做如下笔记。主要通过以下几个知识点为突破口进行学习:

  • block的本质;
  • block的变量捕获;
  • block类型;

一、block的本质

blcok的本质是结构体(__main_block_impl_0)也是一个oc对象(有isa指针)。具体如下;

struct __main_block_impl_0{
    struct __block_impl impl; 
    struct __main_block_desc_0 * Desc; //block描述信息
    ... //捕获的其他的成员变量
}
struct __block_impl{
    void *isa;
    int Flags;//默认为0
    int Reserved;
    void * FuncPtr;//指向函数的地址
}
struct __main_block_desc_0 {
    size_t reservd;//默认为0
    size_t Block_size;// __main_block_impl_0 的占用内存大小
    void (*copy)(struct __main_block_impl_0,struct __main_block_impl_0);
    void(* dispones)(struct __main_block_impl_0)
}

二、关于变量捕获(capture)

到外部的变量在block代码块使用时,block在构造函数会生成一个通类型的同名称的成员变量,并且在构造函数输入传入赋值。

block的捕获机制:

  • 局部变量 auto 通过值传递;
  • 局部变量 static 通过指针传递;
  • 全局变量 不会捕获到 __main_block_impl_0 内部,block 函数直接访问。

局部的自动变量会随时销毁,但是static的指针地址会一直在内存。

全局变量没有作用域谁都可以访问,也就是说函数可以直接访问,不用捕获到block内部,也就是说在__main_block_impl_0 不会生成全局变量成员。

三、block类型。

block本质是结构体但是也是一个oc对象最终是集成NSObject,其isa就是NSObject的指针。

主要类型分为三种:

  • NSGlobalBlock
  • NSStackBlock
  • NSMallocBlock

具体的区别:

block 调用copy后的变化情况:

栈和堆的数据区别: 栈的离开作用域后,数据会销毁;而堆则不会,除非调用release操作。

总结:

block需要注意的就是:变量捕获和类型对应的值的引用。