在研究block的类型之前,首先我们要知道c类语言的程序编译后在内存中的分布(由高位向低位排序):
栈区
:局部变量堆区
:由”alloc”开辟的空间就是在堆区静态区(全局区)
: 静态变量、 全局变量(注:未初始化的在bss)常量区
: 常量代码区
: 二进制代码段
这里我们将MRC和ARC分开讨论:
在MRC下有三种类型的block
NSGlobalBlock:
位于内存全局区、不调用外部变量或者仅调用静态区常量区的”变量”
控制台输出:
NSStackBlock:
位于内存栈区、仅调用栈区变量
控制台输出:
NSMallocBlock:
位于内存堆区、由栈区copy到堆区
控制台输出:
在ARC下,仅存在 NSGlobalBlock
、NSMallocBlock
两种block
我们切换到arc环境,并且将 mallocTest
中的如下代码注释取消
运行得到输出结果:
由此可以判断,在arc下没有 NSStackBlock
类型变量、并且 copy
操作只是对堆区 block
进行了一次引用,既然如此我接着对 NSGlobalBlock
、NSMallocBlock
进行copy操作:
控制台输出:
|
控制台输出:
总结:
- 当block中没有引用任何外部变量时或者仅仅调用静态区变量时,编译器直接将block放在静态区(减少堆区的占用有利于性能的)
- copy 操作对将NSStackBlock拷贝到堆区、对另外两种类型只是强引用
- arc下是没有NSStackBlock类型block的(block被当做对象处理)
附测试代码