Block

Block的三种类型

  • 根据Block在内存中的位置分为三种类型NSGlobalBlock,NSStackBlock, NSMallocBlock

    • NSGlobalBlock:类似函数,位于数据区
    • NSStackBlock:位于栈内存,函数返回后Block将无效
    • NSMallocBlock:位于堆内存
  1. 全局block (__NSGlobalBlock__),定义在函数外面的block是global的;另外如果函数内部的 block,但是没有捕获任何自动变量,那么它也是全局的(ARC和MRC都一样)

  2. 堆block 则是对栈block copy 得来。对全局block copy 不会有任何作用,返回的依然是全局block。 在ARC下,只要在block内部引用外部变量,此时这个block是一个堆block,而在MRC下是栈block

总结:
  • ARC 下

    • 没有使用外部变量 NSGlobalBlock
    • 使用外部变量 堆block
  • MRC 下

    • 没有使用外部变量 NSGlobalBlock
    • 使用外部变量 栈block
  • 对一个栈block 通过copy可以得到堆block

block类型变量内存管理参数为什么要使用 copy

  • 不管再MRC还是在ARC,使用assign 修饰的block,都是栈block
  • 如果block变量内存管理参数适用assign,此时变量是栈block,栈block会被提前释放,导致无法继续使用,会造成EXC_BAD_ACESS错误

block本质

block对象就是一个结构体,里面有isa指针指向自己的类(global malloc stack),有desc结构体描述block的信息,forwarding指向自己或堆上自己的地址,如果block对象截获变量,这些变量也会出现在block结构体中。最重要的block结构体有一个函数指针,指向block代码块。block结构体的构造函数的参数,包括函数指针,描述block的结构体,自动截获的变量(全局变量不用截获),引用到的block变量。(__block对象也会转变成结构体)

block代码块在编译的时候会生成一个函数,函数第一个参数是前面说到的block对象结构体指针。执行block,相当于执行block里面__forwarding里面的函数指针

results matching ""

    No results matching ""