1、autoreleasepool总是会被问到,放在自动释放池中的对象合适被释放?理解不正确的答案:{}出了大括号、出了作用域等等。个人认为参考答案是,1、在不是手动添加的AutoreleasePool时,当前的runloop结束时释放,因为编译器在每个runloop中开始时加入了自动释放池的Push和结束时加入了Pop;2、如果是手动添加的AutoreleasePool,就是在@autorelease{}大括号的时候释放,因为编译器在大括号之后调用的Pop。

 下面有一个例子:
以上是测试代码。
在ios8以下的运行结果是:

这个运行结果也说明了“出了作用域对象就被释放的说法是不正确的”,同时也能发现,对象在viewWillAppear中还没有被释放,而到了viewDidAppear中的时候对象已经被释放了。

再补一张证明确实是在这两个方法之间被释放的图:

我在viewDidLoad讲要结束的时候设置了一个断点,并且在console中设置了对reference变量值变化的监听。当开始继续执行代码,并且改变reference的值时,上图展示了改变的时间点。从图中可以看到,在viewWillAppear之后reference的值被改为了nil,也就是在viewWillAppear之后自动释放池地方了对象。

注:刚在上面写了在ios8之前的结果,因为从ios9开始编译器对NSString的stringWithFormat方法做了改变(优化),下面附一张ios9的结果图:

2、上一条中提到的Autorelease调用Push和Pop

     

上图中展示的是AutoreleasePoolPage的结构图,AutoreleasePool是由若干个AutoreleasePoolPage以双向链表组合而成的。每个AutoreleasePoolPage占有空间的大小是虚拟内存一页的大小(4096bytes字节)
magic:用来校验AutoreleasePoolPage结构的完整性
next:最新添加的autoreleased对象的下一个位置
thread:当前的线程
parent:指向父结点
child:指向子结点
depth:代表深度,从0开始向后递增1
hiwat:high water mark
当next == begin(),表明AutoreleasePoolPage为空;当next == end(),表明AutoreleasePoolPage已满,如下图:

当AutoreleasePoolPage满了之后,就会建立下一个AutoreleasePoolPage对象,新的AutoreleasePoolPage的next指针被初始化在栈底(begin()的位置)。
 
嵌套的AutoreleasePool
     前面只介绍了添加对象的情况,下面说一下释放的时刻:
     每当进行一次objc_autoreleasePoolPush时,runtime向当前的AutoreleasePoolPage中add一个哨兵对象,值为0(nil),效果如下图:

objc_autoreleasePoolPush的返回值是这个哨兵对象的地址,于是在释放的过程中;
     1、根据传入的哨兵对象地址找到哨兵对象所在的AutoreleasePoolPage
     2、在当前AutoreleasePoolPage中,将晚于哨兵对象加入的所有对象发送release消息(可以跨越page),然后移动next指针到正确的位置
     所以知道了AutoreleasePool释放对象的过程之后,嵌套的AutoreleasePool就好理解多了,多层的AutoreleasePool就是对个哨兵对象,每次pop的时候释放上次push的位置(哨兵对象的位置)。
     
 
3、Autorelease的其他
      在ARC中使用@autorelease{}时,编译器将  @autorelease{}转化成:
     void *context = objc_autoreleasePoolPush();
     //{}中的代码
       objc_autoreleasePoolPop(context);//如果不是手动添加的autoreleasePool,就是在当前runLoop结束时调用
     objc_autoreleasePoolPush()是对AutoreleasePoolPage::push()的封装
     objc_autoreleasePoolPop() 是对AutoreleasePoolPage::pop()的封装
 
参考:http://www.cocoachina.com/ios/20141031/10107.html

autoreleasepool的笔记的更多相关文章

  1. IOS学习笔记 O2

    第二章 Objective-C语言基础进阶 一.Objective-C语言写法简化 利用@property快速生成setget方法 1.首先来复习一下setget写法,这是上一节笔记写的setget方 ...

  2. IOS学习笔记 O1

    第一章 Objective-C语言基础 一.OC语言与C语言的比较 C语言是一门面向过程的语言,而OC则是一门面向对象的语言. C语言文件默认保存格式为.c,OC语言默认保存格式为.m,两者头文件格式 ...

  3. Object C学习笔记22-#define 用法

    上一篇讲到了typedef 关键字的使用,可以参考文章 Object C 学习笔记--typedef用法 .而在c中还有另外一个很重要的关键字#define. 一. #define 简介 在C中利用预 ...

  4. Object C学习笔记21-typedef用法

    在上一章的学习过程中遇到了一个关键字typedef,这个关键字是C语言中的关键字,因为Object C是C的扩展同样也是支持typedef的. 一. 基本作用 typedef是C中的关键字,它的主要作 ...

  5. iOS学习笔记之Category

    iOS学习笔记之Category 写在前面 Category是类别(也称为类目或范畴),使用Category,程序员可以为任何已有的类添加方法.使用类别可以对框架提供的类(无法获取源码,不能直接修改) ...

  6. iOS学习笔记之ARC内存管理

    iOS学习笔记之ARC内存管理 写在前面 ARC(Automatic Reference Counting),自动引用计数,是iOS中采用的一种内存管理方式. 指针变量与对象所有权 指针变量暗含了对其 ...

  7. Objective-C 学习笔记(Day 1)

    -------------------------------------------- Hello World //引入头文件 //c中的引入头文件的方式 //#include <stdio. ...

  8. Object C学习笔记10-静态方法和静态属性

    在.NET中我们静态使用的关键字static有着举足轻重的作用,static 方法可以不用实例化类实例就可以直接调用,static 属性也是如此.在Object C中也存在static关键字,今天的学 ...

  9. object - c 语言基础 进阶笔记 随笔笔记

    重点知识Engadget(瘾科技)StackOverFlow(栈溢出)Code4Apprespon魏先宇的程序人生第一周快捷键: Alt+上方向键 跳到最上面  Alt+下方向键 跳到最下面      ...

随机推荐

  1. iPad 控件 UIPopoverPresentationController 使用 iPhone可用

    UIPopoverController 在iOS9之后被废弃了,,, iOS8 新控件UIPopoverPresentationController可运用在iphone和iPad上,使用基本同 UIP ...

  2. 总结一下classpath

    今天好好研究了一下Java的classpath,什么是classpath呢?classpath就是我们输入 java xxx 的时候Java执行环境搜索xxx类文件的路径.指定这个路径有两种方式,第一 ...

  3. HDU 1999 不可摸数

    /* 中文题意: 中文翻译: 题目大意:见红字(例如以下) 解题思路:打表,将每一个数的合数之和存在一个数组之中 难点具体解释:用两个for循环写的,第二个for循环主要是解释两个数相乘不超过这个最大 ...

  4. python 使用dict和set

    dict Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度. 举个例子,假设要根据同学的名字 ...

  5. PHP使用ueditor上传配置

    引入 按照ueditor官网demo, 引入好ueditor之后, 默认是不能进行上传操作的 在上传时,在上传时会有如下图提示 配置上传 在editor/php目录下,有一个config.json文件 ...

  6. HDU 5607 graph(矩阵乘法)

    题意 在一个 \(n\) 个节点 \(m\) 条边的有向图上随机游走,有 \(Q\) 个询问,每次给定一个起点 \(u\) 和步数 \(K\) ,每次回答最后停在每个节点的概率. \(1 \leq n ...

  7. .NET高级代码审计(第三课)Fastjson反序列化漏洞

    0X00 前言 Java中的Fastjson曾经爆出了多个反序列化漏洞和Bypass版本,而在.Net领域也有一个Fastjson的库,作者官宣这是一个读写Json效率最高的的.Net 组件,使用内置 ...

  8. geoserver 地图性能和缓存

    1.什么是GeoWebCache GeoWebCache是地图缓存软件公司成员开发的一个基于java的开源项目.和其他的缓存系统相似,它作为一个客户端和地图服务的代理.它可以单独部署,适用于任何基于W ...

  9. drupal sql 源码解析query.inc 文件

    query.inc 文件: sql语句: $this->condition($field);1707 line public function condition($field, $value ...

  10. mysql insert 事务相关(草稿)

    当 insert 多条语句时初步试了一下是自带事务机制的,如在一个这样的表中: 执行语句 INSERT INTO `t_mytest`(`id`) VALUES (1),(2),(3),(4),(5) ...