iOS AutoreleasePool 原理

AutoreleasePool 的数据结构是一个双向链表, 每个节点都是一个 AutoreleasePoolPage.

AutoreleasePoolPage 是一个栈结构的类, 保存的是添加进 AutoreleasePool 的对象内存地址.

AutoreleasePool 嵌套时, 并不是创建一个新的 pool, 而是当前 pool => hotPage 的栈顶插入一个边界对象, 代表内嵌 pool 的边界 (见下图3). pop 时会依次出栈, 直到(包括)内嵌 pool 的 边界对象(POOL_BBOUNDARY).

  

@autoreleasepool {
    Person *p = [Person new];
}

等价于 

void *atautoreleasepoolobj = objc_autoreleasePoolPush();
Person *p = [[Person new] autorelease];
objc_autoreleasePoolPop(atautoreleasepoolobj);
void *objc_autoreleasePoolPush(void) {
    return AutoreleasePoolPage::push();
}

void objc_autoreleasePoolPop(void *ctxt) {
    AutoreleasePoolPage::pop(ctxt);
}

关键类:  AutoreleasePoolPage 继承自 AutoreleasePoolPageData

next: 保存的是最后一个入栈对象的地址

thread: AutoreleasePool 是与线程绑定的, 代表当前线程

parent: 父节点

child: 子节点

depth: 链表深度, 节点个数

struct AutoreleasePoolPageData
{
#if SUPPORT_AUTORELEASEPOOL_DEDUP_PTRS
    struct AutoreleasePoolEntry {
        uintptr_t ptr: 48;
        uintptr_t count: 16;

        static const uintptr_t maxCount = 65535; // 2^16 - 1
    };
    static_assert((AutoreleasePoolEntry){ .ptr = MACH_VM_MAX_ADDRESS }.ptr == MACH_VM_MAX_ADDRESS, "MACH_VM_MAX_ADDRESS doesn't fit into AutoreleasePoolEntry::ptr!");
#endif

	magic_t const magic;

    // 保存的是最后一个入栈的对象地址
	__unsafe_unretained id *next;

    // 当前线程
	pthread_t const thread;

    // 双向链表
	AutoreleasePoolPage * const parent;
	AutoreleasePoolPage *child;
    
    // 链表的深度,节点个数
	uint32_t const depth;

	uint32_t hiwat;

	AutoreleasePoolPageData(__unsafe_unretained id* _next, pthread_t _thread, AutoreleasePoolPage* _parent, uint32_t _depth, uint32_t _hiwat)
		: magic(), next(_next), thread(_thread),
		  parent(_parent), child(nil),
		  depth(_depth), hiwat(_hiwat)
	{
	}
};

  

push: AutoreleasePoolPage --> next 位置 插入边界对象: POOL_BOUNDARY
 
static inline void *push() 
    {
        id *dest;
        if (slowpath(DebugPoolAllocation)) {
            // Each autorelease pool starts on a new pool page.
            dest = autoreleaseNewPage(POOL_BOUNDARY);
        } else {
            dest = autoreleaseFast(POOL_BOUNDARY);
        }
        ASSERT(dest == EMPTY_POOL_PLACEHOLDER || *dest == POOL_BOUNDARY);
        return dest;
    }

autorelease: obj 入栈;

根据 hotPage (当前 page) 的状态有3种情况

1. hotPage 不为空 && 未满: 直接 add();

2. hotPage 已满: 创建新的 page 节点并关联 当前 page 与 新 page 的 child, parent

3. hotPage 为空: 创建一个 page 节点

然后移动 next; 

static inline id autorelease(id obj)
    {
        ASSERT(!obj->isTaggedPointerOrNil());
        id *dest __unused = autoreleaseFast(obj);
#if SUPPORT_AUTORELEASEPOOL_DEDUP_PTRS
        ASSERT(!dest  ||  dest == EMPTY_POOL_PLACEHOLDER  ||  (id)((AutoreleasePoolEntry *)dest)->ptr == obj);
#else
        ASSERT(!dest  ||  dest == EMPTY_POOL_PLACEHOLDER  ||  *dest == obj);
#endif
        return obj;
    }

static inline id *autoreleaseFast(id obj)
    {
        AutoreleasePoolPage *page = hotPage();
        if (page && !page->full()) {
            return page->add(obj);
        } else if (page) {
            return autoreleaseFullPage(obj, page);
        } else {
            return autoreleaseNoPage(obj);
        }
    }

最终都会调用 add 函数; next 指针移动到下一个位置, 该位置保存的是一个 id 类型的对象的地址

id *add(id obj) {
    ...
    *(next++) = obj;
    ...
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
iOS操作系统是由苹果公司开发的移动操作系统,其工作原理可以归纳为以下几个方面: 1. 内核:iOS操作系统基于XNU内核,这是一个混合内核,同时支持微内核和宏内核的特性。它负责处理硬件和软件之间的交互,并提供了一些基本的服务和资源,例如内存管理、进程管理、线程管理等。 2. 硬件抽象层:为了支持多种不同的硬件设备,iOS操作系统引入了硬件抽象层。它提供了一组统一的接口,使得应用程序可以使用相同的代码来访问不同类型的硬件设备。 3. 应用程序框架:iOS操作系统提供了一些预定义的应用程序框架,例如UIKit、Foundation等。这些框架为开发人员提供了一些共享的代码和资源,可以使得开发人员更加高效地开发应用程序。 4. 安全模型:iOS操作系统采用了一系列安全措施来保护用户数据和系统安全。其中包括数据加密、应用程序沙盒、代码签名等。 5. 应用程序生命周期管理:iOS操作系统负责管理应用程序的生命周期,包括启动、运行、挂起和终止等。 6. 用户界面:iOS操作系统提供了一个直观、易用的用户界面,包括多点触控、手势识别等功能,使得用户可以更加方便地使用设备。 总之,iOS操作系统的工作原理是一个复杂的系统工作流程,其中涉及到许多不同的组件和技术。这些组件和技术共同工作,使得iOS操作系统能够提供优秀的性能和用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值