block内存篇

本文目的:对Block内存问题更加了解
概念理解:一种数据类型或比较特殊的对象,相当于一个指向函数的指针,该指针指向一段封装代码,调用block块代码好比调用该指针指向的函数代码
block分类:
  • NSGlobalBlock:位于全局静态区。
  • NSStackBlock:位于栈区,函数返回时被销毁
  • NSMallocBlock:位于堆区,当引用计数为0时被销毁,由NSStackBlock从栈区copy到堆区

 

 

 

 

 

 

 

 

 

 

栈区(stack):由系统自动分配,一般存放函数参数值、局部变量的值等。由编译器自动创建与释放。其操作方式类似于数据结构中的栈,即后进先出、先进后出的原则

堆区(heap):一般由程序员申请并指明大小,最终也由程序员释放。如果程序员不释放,程序结束时可能会由OS回收。

全局区/静态区:顾名思义,全局变量和静态变量存储在这个区域。只不过初始化的全局变量和静态变量存储在一块,未初始化的全局变量和静态变量存储在一块。程序结束后由系统释放。

文字常量区:这个区域主要存储字符串常量。程序结束后由系统释放。

程序代码区:这个区域主要存放函数体的二进制代码

例子:
int a = 0; // 全局初始化区
char *p1; // 全局未初始化区
main {
    int b; //
    char s[] = "abc"; //
    char *p2; //
    char *p3 = "123456"; // 123456\0在常量区,p3在栈上
    static int c =0// 全局静态初始化区
    p1 = (char *)malloc(10);
    p2 = (char *)malloc(20); // 分配得来的10和20字节的区域就在堆区
    strcpy(p1, "123456"); // 123456\0在常量区,这个函数的作用是将"123456" 这串字符串复制一份放在p1申请的10个字节的堆区域中。
    // p3指向的"123456"与这里的"123456"可能会被编译器优化成一个地址。
}
block区分:
NSGlobalBlock:未引用外部任何变量即为NSGlobalBlock
NSStackBlock:引用外部变量,且只有一次执行,block返回后栈区将释放该block

NSMallocBlock:当需要多次执行时,就会把该block从栈中copy到堆中,以便多次执行
block-arc/mrc内存问题:
mrc下引用外部变量,则block是在栈区;arc下block默认生成于栈区,然后自动copy至堆区。
mrc环境:
1.当打印myBlock时发现mrc下对外部变量引用是在栈区,并没有进行copy至堆区
2.myBlock内部对外部变量stopName进行引用,执行block的时候内存计数器仍为1,证明retain失效,从而证明栈区无法release、retain,由系统自动分配和释放内存;
3.对myBlock进行copy,发现yourBlock是在堆区,stopName内存计数器+1

arc环境:
执行myBlock,发现是在堆区,证明arc环境下回自动将block从栈区copy至堆区


 代码分享:内容包括定义、使用、循环引用、内存覆盖等问题例子

百度云:http://pan.baidu.com/s/1c1Y21hA

posted @ 2016-04-17 17:28  -Eazy-  阅读(988)  评论(0)    收藏  举报