在 OC 中,Block 有如下三种类型:
如下是具体的描述
_NSConcreteGlobalBlock 是全局的静态block,不会访问任何外部变量。这种不捕捉外界变量的block是不需要内存管理的,这种block不存在于Heap或是Stack而是作为代码片段存在,类似于C函数。
_NSConcreteStackBlock 保存在栈中的block,当函数返回时会被销毁。
_NSConcreteMallocBlock 保存在堆中的block,当引用计数为0时会被销毁。
在 MRC 下 block 在创建时是 stack 对象,如果我们需要在离开当前函数仍能够使用我们创建的 block 。我们就需要把它拷贝到堆上以便进行以引用计数为基础的内存管理。
文档里是这么说的:
With the exception of retains done as part of initializing a strong parameter variable or reading a weak variable, whenever these semantics call for retaining a value of block-pointer type, it has the effect of a Block_copy. The optimizer may remove such copies when it sees that the result is used only as an argument to a call.
即在 ARC 下创建的 block 仍然是 _NSConcreteStackBlock 类型,当 block 被引用或返回时,ARC 帮助我们完成了 copy 和内存管理的工作。这种 block 变成了 _NSConcreteMallocBlock 类型。