首页 > 其他分享 >iOS开发基础123-自动释放池

iOS开发基础123-自动释放池

时间:2024-07-17 16:58:07浏览次数:11  
标签:释放 void iOS autoreleasePoolPage objc 123 内存 页面

自动释放池(Autorelease Pool)是Objective-C中用于管理内存的一个重要机制,它帮助开发者简化内存管理的工作。自动释放池的核心概念是将对象放入池中,在某个时刻由系统统一释放这些对象。这种机制在iOS和macOS的应用开发中广泛使用,尤其是在事件循环和线程运行时。

为了深入理解其底层实现,首先需要了解其核心数据结构、工作原理及实际应用。

一、核心数据结构

自动释放池的核心数据结构是 _objc_autoreleasePoolPage,每个页面包含一个固定大小的空间,用于存储对象。其具体定义如下:

struct _objc_autoreleasePoolPage {
    _objc_autoreleasePoolPage * const parent;
    _objc_autoreleasePoolPage *child;
    void * const *_next;
    void **_begin;

    void **begin() const { return _begin; }
    void **end() const { return (*this + PAGE_SIZE) - 1; }
};
  • parent:指向上一个页面,形成一个链表结构。
  • child:指向下一个页面,形成一个链表结构。
  • _next:指向当前池页中下一个可用的位置。
  • _begin:指向当前池页的起始位置。

每当一个自动释放池创建时,一个新的 _objc_autoreleasePoolPage 页面会被分配。

二、自动释放池的工作原理

1. Autorelease Pool 的创建和销毁

当创建一个自动释放池时,会调用 objc_autoreleasePoolPush 函数:

void *objc_autoreleasePoolPush(void) {
    return AutoreleasePoolPage::push();
}

这将触发 _objc_autoreleasePoolPage::push 方法,该方法分配一个新的 Autorelease Pool Page,并返回其地址。

AutoreleasePoolPage * AutoreleasePoolPage::push(void) {
    // 当前页面满了,创建新页面
    if (next == end()) {
        return new AutoreleasePoolPage(this);
    }
    // 否则,在当前页面继续添加
    *next++ = POOL_BOUNDARY;
    return this;
}

在销毁一个自动释放池时,会调用 objc_autoreleasePoolPop 函数:

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

这将触发 _objc_autoreleasePoolPage::pop 方法,销毁当前页面中所有的对象,并释放池页内存。

void AutoreleasePoolPage::pop(void *token) {
    // 遍历池中的所有对象,发送 release 消息
    id *stop = (id*)token;
    while (next > stop) {
        (*--next)->release();
    }
    // 回溯到父节点
    if (parent) {
        parent->child = nullptr;
    }
    free(this);
}

2. Autorelease 的实现

当一个对象调用 autorelease 方法时,会将其添加到当前的 Autorelease Pool Page 中:

id objc_autorelease(id obj) {
    return AutoreleasePoolPage::autorelease(obj);
}

这个调用会触发 _objc_autoreleasePoolPage::autorelease 方法:

id AutoreleasePoolPage::autorelease(id obj) {
    // 当前页面满了,创建新页面
    if (next == end()) {
        return autoreleaseFullPage(obj);
    }
    // 否则,在当前页面添加对象
    *next++ = obj;
    return obj;
}

三、实际应用及优化

1. 应用场景

自动释放池主要用于临时对象的管理,尤其是在事件循环中。比如,每一次 RunLoop 迭代都会创建并销毁一个自动释放池,以确保临时对象不会占用过多内存:

while (runLoopActive) {
    @autoreleasepool {
        // 处理输入,计时器,事件等
        ...
    }
}

2. 内存优化

在高度频繁创建和销毁对象的场景下,自动释放池通过批量释放内存来降低内存碎片并提升性能。注意在长时间运行的任务中,应当手动创建并销毁自动释放池,防止大量临时对象堆积:

- (void)processLargeDataset {
    for (int i = 0; i < largeDataset.count; i++) {
        @autoreleasepool {
            // 处理每个数据
            ...
        }
    }
}

四、总结

自动释放池的底层实现通过 _objc_autoreleasePoolPage 页面来管理对象,创建和销毁池时分别调用objc_autoreleasePoolPushobjc_autoreleasePoolPop 函数。每个页面使用固定大小的空间存储对象,并在池销毁时批量发送 release 消息。这种机制有效简化了内存管理,并在事件循环和高频临时对象场景下提供了良好的优化。

这种理解帮助开发人员合理地使用自动释放池,防止内存泄漏和内存过多占用,提升应用的性能和稳定性。

标签:释放,void,iOS,autoreleasePoolPage,objc,123,内存,页面
From: https://www.cnblogs.com/chglog/p/18307811

相关文章

  • vue请求接口常用写法(axios)
    1.项目根目录下新建一个utils文件夹,并新建一个request.js文件(注意:是以axios方法请求的,所以需要先安装axios或cdn引入)安装:npmnpminstallaxios-Syarnyarnaddaxios-Scdn<scriptsrc="https://unpkg.com/axios/dist/axios.min.js"></script>&&配置代码imp......
  • iOS开发基础119-组件化
    一、引言组件化是将应用程序分解成多个独立模块的设计方法,这些模块可以单独开发、测试和维护。对于大型iOS项目,组件化能够提高开发效率、降低耦合、增加代码复用性,并且使项目更易维护。本文将详细介绍如何在iOS项目中实现组件化,包括本地组件管理和远程组件管理。二、为什么......
  • iOS开发基础120-通知与线程
    NSNotificationCenter是iOS和macOS开发中用于消息传递的机制,可以在多个对象之间实现解耦的事件通知。理解NSNotificationCenter的线程模型对正确使用这一工具至关重要。NSNotificationCenter的线程模型1.消息发送线程当你通过NSNotificationCenter发送消息时,消息会......
  • iOS开发基础108-Runtime
    Objective-C的Runtime是一个强大的特性,它让语言具备了很多灵活的动态能力。通过Runtime,开发者可以在运行时解析类、方法、变量,并进行动态的消息传递、方法交换等操作。以下将详细介绍Runtime,包括具体的应用场景和底层实现原理。什么是RuntimeRuntime是Objective-C运行......
  • iOS开发基础117-Hybrid
    HybridHybrid(混合)开发是一种结合了Web技术和原生应用开发技术的方法,旨在简化跨平台应用开发。通过Hybrid开发,开发者可以用HTML、CSS和JavaScript等前端技术编写代码,并将其运行在一个内嵌的浏览器环境中,从而实现跨平台的移动应用。什么是Hybrid开发?Hybrid开发主要是指将应用的用......
  • iOS开发基础116-性能监控
    在iOS开发中,性能监控是确保应用流畅运行和用户体验的关键。常用的性能监控工具能够帮助开发者实时监控系统性能,检测和诊断性能问题。下面列举几款常用的iOS性能监控工具,深入解析其底层原理、优缺点。1.InstrumentsInstruments是由Apple官方提供的用于性能分析和调试的工具。它......
  • iOS开发基础114-YYCache
    YYCache是一个高性能、易用的缓存组件,广泛用于iOS开发中。其设计宗旨是高效且灵活,可以处理不同类型的缓存需求。以下将介绍YYCache的常见应用场景,并深入分析其底层原理。应用场景1.图片缓存在展示大量图像的应用(比如社交媒体应用)中,缓存机制可以大幅减少网络请求,提升用户......
  • iOS开发基础115-Socket
    在现代网络编程中,Socket(套接字)是实现网络通信的主要机制。Socket提供了端到端的双向通信接口,使得不同主机上的进程能够通过网络直接通信。在iOS开发中,经常需要使用Socket进行网络请求、实时通信(如聊天、游戏等)。以下将详细介绍Socket的概念,并列举iOS开发中常用的三方Socket框架,深......
  • iOS开发基础113-Unity3D
    在iOS项目中接入Unity3D项目可以创建更复杂且互动性强的应用。Unity3D通常用于游戏开发,它可以与原生iOS项目进行集成。以下是详细的步骤和示例代码,且深入讨论其底层原理。步骤1.创建Unity3D项目打开Unity3D并创建一个新项目。完成项目场景和逻辑编写。在Unity3D项目中,设置i......
  • iOS开发基础112-GCD
    GrandCentralDispatch(GCD)在iOS中的常见运用场景GCD是Apple提供的多线程编程技术,旨在提供高效、轻量级的方式来执行并发任务。GCD使得管理线程变得简单且提高了应用程序的性能。以下是GCD在iOS中的一些常见运用场景,并详细介绍其底层原理。1.异步任务处理场景:网络请求使用GCD......