1、结构

struct magic_t {
    /* 魔法 */
    static const uint32_t M0 = 0xA1A1A1A1;
#   define M1 "AUTORELEASE!"
    static const size_t M1_len = 12;
    uint32_t m[4];
/* 省略各种方法 */
#   undef M1
}; /* AutotRelease 重要:重载了new和delete运算符号,使每个Page对象固定大小 */
class AutoreleasePoolPage 
{
#define POOL_SENTINEL nil
    static pthread_key_t const key = AUTORELEASE_POOL_KEY; /* TSD __PTK_FRAMEWORK_OBJC_KEY3 */
    static uint8_t const SCRIBBLE = 0xA3;  // 0xA3A3A3A3 after releasing
    static size_t const SIZE = 
#if PROTECT_AUTORELEASEPOOL
        PAGE_MAX_SIZE;  // must be multiple of vm page size
#else
        PAGE_MAX_SIZE;  // size and alignment, power of 2 (CGS. 4096 < bytes per 80386 page >)
#endif
    static size_t const COUNT = SIZE / sizeof(id);
    magic_t const magic;
    id *next;   /* objc 对象列表指向下一个未使用的区域 */
    pthread_t const thread; /* page对应线程 */
    /* 链表结构 */
    AutoreleasePoolPage * const parent; /* 父 */
    AutoreleasePoolPage *child;         /* 子 */
    uint32_t const depth;               /* 链表深度 */
    uint32_t hiwat;
    // SIZE-sizeof(*this) bytes of contents follow
//省略各种方法
//00000哨兵分割线
//各种objc对象,
}

2、 每个线程对应一个AutoReleasePoolPage 的对象列表

2.1) 线程销毁的时候,释放AutoReleasePoolPage 以及所有对象

2.2) AutoReleasePoolPage 为C++对象,由于重载了new 和 delete 运算符,确保每一个Page分配固定大小(貌似4K)。在类的实例变量/方法列表后存储Foundation对象。而类的next 成员变量则指向下一个Foundation对象。AutoReleasePoolPage 有判断是否为空和满的成员函数,以此来判断当前线程是否新创建一个AutoReleasePool对象。没创建一个对象,都会设置parent、chilid属性,构成双向链表,而hotPage则是存储在线程的本地存储中。系统初始化时会给线程初始化钩子函数  int r __unused = pthread_key_init_np(AutoreleasePoolPage::key,  AutoreleasePoolPage::tls_dealloc); 确保在线程销毁的时候,释放AutoReleasePool, 由于hotPage存存在TLS中,并且page为双向链表,可以通过hotPage遍历整个Page俩表,确保释放Page对象。

每个oc对象发送 autorelease 消息或者使用__autorelease 修饰的时候,从当前线程取出hotPage(), 整个函数从线程本地存储中取,如果没有AutoReleasePoolPage链表则创建一个,否则取出AutoReleasePoolPage,查看是否full,如果full则创建一个新的AutoReleasePoolPage,设置parent 和 child属性, 然后设置为hotPage(存入线程中本地存储中 TLS)。

  @autoreleasepool {

    //some code

  }

所有使用 @autoreleasepool block起来的代码,都会在形成

  void *pool = AutoReleasePoolPage::push();

  //some code

  AutoReleasePoolPage::pop(pool);

3、 主线程AutoReleasePoolPage何时pop?

文档中说每个 event loop(鼠标事件、点击事件等)都会在事件的will 时 pool->push(),did时 pool->pop(void *).。OS 会在主线程的RunLoop循环注册一些列观察者,在进入时调用 void *pool = AutoReleasePoolPage::push(); ,退出时调用 AutoReleasePoolPage::pop(pool); 这样子确保每一次循环都进行pool的释放。

												

Objective-C RunTime 学习笔记 之 AutoReleasPool的更多相关文章

  1. 我的runtime学习笔记

    0.简介: OC方法不同于C语言函数,属于动态调用过程,在编译的时候并不能决定真正调用哪个函数,只有在真正运行的时候才会根据函数的名称找到对应的函数来调用. 至于其他理论上的东西不必讲太多,编程讲的就 ...

  2. runtime学习笔记

    获取属性objc_property_t * propertys = class_copyPropertyList(clazz, &outCount); 获取属性名NSString * key ...

  3. iOS Runtime学习笔记

    Associated Objects: @interface NSObject (AssociatedObject) @property (nonatomic, strong) id associat ...

  4. Objective-C学习笔记---构造函数和析构函数

    简单的讲,构造函数就是在创建一个对象的时候起到初始化的作用,对这个对象里的一些成员变量进行初始化,析构函数就是在对象被删除进行一些清理工作,也就是专门的扫尾工作,下面用代码来进行具体说明. 一.构造函 ...

  5. Objective-C RunTime 学习笔记 之 消息转发流程

    1) 当向某个对象发送消息时,先从cache(cache_t)中查找方法对象(method_t),如果找到则进行回调:否则通过查找对象的类(元类)定义中方法列表,一直追溯到NSObject, 如果找到 ...

  6. Objective-C RunTime 学习笔记 之 atomic/nonatomic 关键字

    atomic修饰的是变量/方法,对于可变对象的指针变量是安全的,内部实现加了锁,但是对可变对象本身没什么影响,不安全还是不安全.另外atomic仅仅对编译器生产的getter.setter有效,如果自 ...

  7. Objective-C RunTime 学习笔记 之 基础结构体

    1.OC 运行期常用对象结构体 基本的结构体定义 typedef objc_class Class; /* 类 */ typedef objc_object *id; /* 各种类型,只要第一个字段为 ...

  8. Flink学习笔记:Flink Runtime

    本文为<Flink大数据项目实战>学习笔记,想通过视频系统学习Flink这个最火爆的大数据计算框架的同学,推荐学习课程: Flink大数据项目实战:http://t.cn/EJtKhaz ...

  9. objc_msgSend消息传递学习笔记 – 消息转发

    该文是 objc_msgSend消息传递学习笔记 – 对象方法消息传递流程 的基础上继续探究源码,请先阅读上文. 消息转发机制(message forwarding) Objective-C 在调用对 ...

随机推荐

  1. windows环境下redis启动加到服务中

    前置条件: 1.命令运行在redis-server.exe目录下  2.cmd命令  安装命令: redis-server.exe --service-install redis.windows.co ...

  2. nginx通过反向代理实现未备案域名访问详解

    本方法实现前提是8123端口(也可以是其他端口)面对互联网打开.server里面监听80端口,然后反向代理8123端口.1.其中server_name部分是我的域名可以替换成其他想要的域名2.8123 ...

  3. 同时执行多个$.getJSON() 数据混乱的问题的解决

    在执行之前加$.ajaxSettings.async = false; (同步执行)执行你的代码之后及时恢复为$.ajaxSettings.async = true: (异步执行)不然影响别的地方的需 ...

  4. 定时 清理 elasticsearch 6.5.4 的 索引 文件

    #!/bin/sh ip='127.0.0.1' port=' day=`date -d "2 days ago" +%Y%m%d` #day=`date -d "5 h ...

  5. 第一篇:你不一定了解的"推荐系统"

    前言 [推荐系统 - 基础教程]可能是穆晨的所有博文里,最有趣最好玩的一个系列了^ ^. 作为该系列的[入门篇],本文将轻松愉快地向读者介绍推荐系统这项大数据领域中的热门技术. 为什么要有推荐系统? ...

  6. 【Zookeeper系列】Zookeeper命令操作(转)

    原文链接:https://www.cnblogs.com/sunddenly/p/4031881.html 一.Zookeeper的四字命令 Zookeeper支持某些特定的四字命令字母与其的交互.他 ...

  7. 19款Windows实用软件推荐,满满的干货,总有一款是你必备的

    https://post.smzdm.com/p/745799/ 追加修改(2018-08-20 12:28:23):一些追加内容: 很多人都在吐槽为什么推荐Clover,这里我说明一下,就我了解到的 ...

  8. Java基础知识点总结

    前言 本文主要是我之前复习Java基础原理过程中写的Java基础知识点总结.Java的知识点其实非常多,并且有些知识点比较难以理解,有时候我们自以为理解了某些内容,其实可能只是停留在表面上,没有理解其 ...

  9. pandas功能使用rename, reindex, set_index 详解

    pandas rename 功能 在使用 pandas 的过程中经常会用到修改列名称的问题,会用到 rename 或者 reindex 等功能,每次都需要去查文档 当然经常也可以使用 df.colum ...

  10. springboot中Properties注解的实现

    关于@PropertySources注解的理解:http://www.imooc.com/article/252889?block_id=tuijian_wz public interface Pro ...