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 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对象,
}
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)。
无论遇到什么困难、一往直前

浙公网安备 33010602011771号