欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

Objective-C RunTime 学习笔记 之 AutoReleasPool

发布时间:2025/4/14 68 豆豆
生活随笔 收集整理的这篇文章主要介绍了 Objective-C RunTime 学习笔记 之 AutoReleasPool 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

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 nilstatic pthread_key_t const key = AUTORELEASE_POOL_KEY; /* TSD __PTK_FRAMEWORK_OBJC_KEY3 */static uint8_t const SCRIBBLE = 0xA3;  // 0xA3A3A3A3 after releasingstatic size_t const SIZE =  #if PROTECT_AUTORELEASEPOOLPAGE_MAX_SIZE;  // must be multiple of vm page size #elsePAGE_MAX_SIZE;  // size and alignment, power of 2 (CGS. 4096 < bytes per 80386 page >) #endifstatic 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的释放。

转载于:https://www.cnblogs.com/chengsh/p/8630628.html

总结

以上是生活随笔为你收集整理的Objective-C RunTime 学习笔记 之 AutoReleasPool的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。