陈斌彬的技术博客

Stay foolish,stay hungry

iOS-关于block在内存中的位置

block块的存储位置(block入口的地址)可能存放在3个地方:代码区(全局区)、堆区、栈区(ARC情况下会自动拷贝到堆区、因此ARC下只有两个地方:代码区和堆区)。

  • 代码区:不访问出去栈区的变量(如局部变量),且不访问堆区的变量(如用alloc创建的对象)时,此时block存放在代码区;
  • 堆区:如果访问了处于堆区的变量(如局部变量),或堆区的变量(如用alloc创建的对象),此时block存方在堆区;–需要注意

    • 实际是放在栈区,在ARC情况下油自动拷贝到堆区,如果不是ARC则存放在栈区,所在函数执行完毕就回释放,想再外面调用需要用copy指向它,这样就拷贝到了堆区,strong属性不会拷贝、会造成野指针错区。(需要理解ARC是一种编译器特性,即编译器在编译时在核实的地方插入retain、release、autorelease,而不是iOS的运行时特性)。

    • 此外代码存在堆区时,需要注意,因为堆区不像代码区不变化,堆区是动态的(不断的创建销毁),当没有强指针指向的时候就会被销毁,如果再去访问这段代码时,程序就会崩溃!所以此种情况在定义block属性时需要指定为strong or copy。block是一段代码,即不可变,所以使用copy也不会深拷贝。

简单记忆:

  • Block如果没有引用外部变量,保存在全局区(MRC/ARC一样)
  • Block如果引用外部变量,ARC保存在 堆区; MRC保存在 栈区必须用copy修饰block;

Resource Reference