在 ARC 中,捕获了外部变量的 block 的类会是 __NSMallocBlock__ 或者 __NSStackBlock__,如果 block 被赋值给了某个变量,在这个过程中会执行 __Block__copy 将原有的 __NSStakeBlock__ 变成 __NSMallocBlock__ ;但是如果 block没有赋值给某个变量,那他的类型就是 __NSStakeBlock__ ;没有捕获外部变量的 block 的类会是 __NSGlobalBlock__ 即不再对上,也不在栈上,它类似 C 语言函数一样会在代码段中。
在非 ARC 中,捕获了外部变量的 block 的类会是 __NSStackBlock__ ,放在栈上,没有捕获外部变量的 block 时与 ARC 环境下情况相同。
block 中的 isa 指向的是该 block 的 Class 。在 block runtime 中,第一了6种类型:
_NSConcreteStackBlock 栈上创建的block
_NSConcreteMallocBlock 堆上创建的block
_NSConcreteGlobalBlock 作为全局变量的block
_NSConcreteWeakBlockVariable
_NSConcreteAutoBlock
_NSConcreteFinalizingBlock
我们能接触到的主要是前三种,后三种用于 GC 不再讨论...
当 struct 第一次被创建时,它是存在于该函数的栈帧上的,其 Class 是固定的 __NSStackBlock 。其捕获的变量是会赋值到结构体的成员上,所以当 block 初始完成后,捕获到的变量不能更改。