基础知识 - BLOCK


什么是block
将函数及其可执行上下文封装起来的对象(isa指针)

block本质
通过clang可以查看源码实现
函数调用
本质是一个对象

block类型(MRC)
全局block NSGlobalBlock 未访问外部变量或者只访问了静态变量(包括全局静态变量和局部静态变量)和全局变量
栈block NSStackBlock 访问局部变量
堆block NSMallocBlock __NSStackBlock__调用了copy

block类型(ARC)
全局block NSGlobalBlock 未访问外部变量或者只访问了静态变量(包括全局静态变量和局部静态变量)和全局变量
堆block NSStackBlock 访问局部变量

block类型总结
MRC环境下,不访问外部变量或者只访问静态变量或者全局变量的为全局block,只访问局部变量(不包含静态变量)的为栈block,栈block执行copy操作会变成堆block,ARC状态下会自动把栈block copy到堆上,所以arc状态下么有栈block

block截获变量
局部变量

  • 基本数据类型 截获其值
  • 对象类型 截获其值 连同该对象所有权修饰符一起截获
  • 静态局部变量 指针截获
    全局变量
  • 静态全局变量 不截获
  • 全局变量 不截获

__block修饰符
局部变量

  • 基本数据类型 需要__block
  • 对象类型 需要__block
  • 静态局部变量 不需要__block
    全局变量
  • 静态全局变量 不需要__block
  • 全局变量 不需要__block

对被截获变量发生赋值操作,需要用到__block修饰符
__block修饰的变量最终变成了对象
使用 和 赋值 的理解
__block会把变量变成一个拥有isa指针和forwarding指针的对象,forwarding对象指向对象本身,通过forwarding去修改变量值

block内存管理
block发生赋值操作时会执行copy,栈block在内存中的地址copy一份到堆中,这样,栈中block作用域结束后,栈block就会释放掉,而堆block由于在堆中,当堆中block作用域结束后,会在最近一次autoreleasepool执行结束释放掉

__block来修饰变量
__block修饰变量,会把变量变成一个对象,该对象有它自己的isa指针和forwarding指针,forwarding指向该对象本身,当block发生copy操作后,同样会把__block修饰的变量也copy一份在堆中,此时原对象的forwarding指向堆中block中的变量,堆中变量forwarding指针指向变量本身

block循环引用
block对象通过copy关键字修饰的,所有当前对象对block强引用,block内使用的变量又被当前对象强引用,相当于block强引用当前对象,这样就形成了引用循环
通过__weak修饰可以解决循环引用的问题,
根据block捕获变量的特性,会连其所有权修饰符一起捕获,这样,当我们使用__weak修饰时,__weak修饰符会被捕获到block中,这样,block与变量变成了弱引用关系,当变量被释放后,block也会被被释放

posted @ 2022-08-04 10:17  qqcc1388  阅读(7)  评论(0)    收藏  举报