AutoreleasePool 理解

【iOS】——AutoReleasePool底层原理及总结 自动释放池是由以双向链表的方式实现的,每一个所占内存大小为4096字节,其中56字节用于存储结构体中的成员变量。autoreleasepool在初始化时,内部是调用方法autoreleasepool在调用析构函数释放时,内部是调用方法入栈(push)在页中压栈普通对象主要是通过next指针递增进行的当没有pool,即只有空占位符(存储在tls中)时,则创建页,压栈哨兵对象。 阅读详情

AutoreleasePool(自动释放池)是OC中的一种内存自动回收机制,它可以延迟加入AutoreleasePool中的变量release的时机。在正常情况下,创建的变量会在超出其作用域的时候release,但是如果将变量加入AutoreleasePool,那么release将延迟执行。

AutoreleasePool创建和释放

  • App启动后,苹果在主线程 RunLoop 里注册了两个 Observer,其回调都是 _wrapRunLoopWithAutoreleasePoolHandler()。
  • 第一个 Observer 监视的事件是 Entry(即将进入Loop),其回调内会调用 _objc_autoreleasePoolPush() 创建自动释放池。其 order 是-2147483647,优先级最高,保证创建释放池发生在其他所有回调之前。
  • 第二个 Observer 监视了两个事件: BeforeWaiting(准备进入休眠) 时调用_objc_autoreleasePoolPop() 和 _objc_autoreleasePoolPush() 释放旧的池并创建新池;Exit(即将退出Loop) 时调用 _objc_autoreleasePoolPop() 来释放自动释放池。这个 Observer 的 order 是 2147483647,优先级最低,保证其释放池子发生在其他所有回调之后。
  • 在主线程执行的代码,通常是写在诸如事件回调、Timer回调内的。这些回调会被 RunLoop 创建好的 AutoreleasePool 环绕着,所以不会出现内存泄漏,开发者也不必显示创建 Pool 了。

也就是说AutoreleasePool创建是在一个RunLoop事件开始之前(push),AutoreleasePool释放是在一个RunLoop事件即将结束之前(pop)。
AutoreleasePool里的Autorelease对象的加入是在RunLoop事件中,AutoreleasePool里的Autorelease对象的释放是在AutoreleasePool释放时。

AutoreleasePool实现原理

在终端中使用clang -rewrite-objc命令将下面的OC代码重写成C++的实现:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    
    @autoreleasepool {
        NSLog(@"Hello, World!");
    }
 
    return 0;
}

在cpp文件代码中我们找到main函数代码如下:

int main(int argc, const char * argv[]) {

    /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 
        NSLog((NSString *)&__NSConstantStringImpl__var_folders_kb_06b822gn59df4d1zt99361xw0000gn_T_main_d39a79_mi_0);
    }

    return 0;
}

可以看到苹果通过声明一个__AtAutoreleasePool类型的局部变量__autoreleasepool实现了@autoreleasepool{}。
__AtAutoreleasePool的定义如下:

extern "C" __declspec(dllimport) void * objc_autoreleasePoolPush(void);
extern "C" __declspec(dllimport) void objc_autoreleasePoolPop(void *);

struct __AtAutoreleasePool {
  __AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}
  ~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}
  void * atautoreleasepoolobj;
};

根据构造函数和析构函数的特点(自动局部变量的构造函数是在程序执行到声明这个对象的位置时调用的,而对应的析构函数是在程序执行到离开这个对象的作用域时调用),我们可以将上面两段代码简化成如下形式:

int main(int argc, const char * argv[]) {

    /* @autoreleasepool */ {
        void *atautoreleasepoolobj = objc_autoreleasePoolPush();
        NSLog((NSString *)&__NSConstantStringImpl__var_folders_kb_06b822gn59df4d1zt99361xw0000gn_T_main_d39a79_mi_0);
        objc_autoreleasePoolPop(atautoreleasepoolobj);
    }

    return 0;
}

至此,我们可以分析出,单个自动释放池的执行过程就是objc_autoreleasePoolPush() —> [object autorelease] —> objc_autoreleasePoolPop(void *)。

来看一下objc_autoreleasePoolPush 和 objc_autoreleasePoolPop 的实现:

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

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

上面的方法看上去是对 AutoreleasePoolPage 对应静态方法 push 和 pop 的封装。
下面分析一下AutoreleasePoolPage的实现,揭开AutoreleasePool的实现原理。

AutoreleasePoolPage实现

AutoreleasePoolPage介绍

AutoreleasePoolPage 是一个 C++ 中的类,它在 NSObject.mm 中的定义是这样的:

class AutoreleasePoolPage {
#   define EMPTY_POOL_PLACEHOLDER ((id*)1)

#   define POOL_BOUNDARY nil
    static pthread_key_t const key = AUTORELEASE_POOL_KEY;
    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
#endif
    static size_t const COUNT = SIZE / sizeof(id);

    magic_t const magic;
    id *next;
    pthread_t const thread;
    AutoreleasePoolPage * const parent;
    AutoreleasePoolPage *child;
    uint32_t const depth;
    uint32_t hiwat;
};
  • magic 检查校验完整性的变量
  • next 指向新加入的autorelease对象
  • thread page当前所在的线程,AutoreleasePool是按线程一一对应的(结构中的thread指针指向当前线程)
  • parent 父节点 指向前一个page
  • child 子节点 指向下一个page
  • depth 链表的深度,节点个数
  • hiwat high water mark 数据容纳的一个上限
  • EMPTY_POOL_PLACEHOLDER 空池占位
  • POOL_BOUNDARY 是一个边界对象 nil,之前的源代码变量名是 POOL_SENTINEL哨兵对象,用来区别每个page即每个 AutoreleasePoolPage 边界
  • PAGE_MAX_SIZE = 4096, 为什么是4096呢?其实就是虚拟内存每个扇区4096个字节,4K对齐的说法。
  • COUNT 一个page里对象数

双向链表

AutoreleasePool并没有单独的结构,而是由若干个AutoreleasePoolPage以双向链表的形式组合而成的栈结构(分别对应结构中的parent指针和child指针)

parent和child就是用来构造双向链表的指针。parent指向前一个page, child指向下一个page。
一个AutoreleasePoolPage的空间被占满时,会新建一个AutoreleasePoolPage对象,连接链表,后来的autorelease对象在新的page加入。

objc_autoreleasePoolPush

每当自动释放池调用objc_autoreleasePoolPush时都会把边界对象放进栈顶,然后返回边界对象,用于释放。

atautoreleasepoolobj = objc_autoreleasePoolPush();

atautoreleasepoolobj就是返回的边界对象(POOL_BOUNDARY)

push实现如下:

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

它调用AutoreleasePoolPage的类方法push:

static inline void *push() {
   return autoreleaseFast(POOL_BOUNDARY);
}

在这里会进入一个比较关键的方法autoreleaseFast,并传入边界对象(POOL_BOUNDARY):

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);
   }
}

上述方法分三种情况选择不同的代码执行:

  • 有 hotPage 并且当前 page 不满,调用 page->add(obj) 方法将对象添加至 AutoreleasePoolPage 的栈中
  • 有 hotPage 并且当前 page 已满,调用 autoreleaseFullPage 初始化一个新的页,调用 page->add(obj) 方法将对象添加至 AutoreleasePoolPage 的栈中
  • 无 hotPage,调用 autoreleaseNoPage 创建一个 hotPage,调用 page->add(obj) 方法将对象添加至 AutoreleasePoolPage 的栈中

最后的都会调用 page->add(obj) 将对象添加到自动释放池中。
hotPage 可以理解为当前正在使用的 AutoreleasePoolPage。

AutoreleasePoolPage::autorelease(id obj)

autorelease方法的实现,先来看一下方法的调用栈:

- [NSObject autorelease]
└── id objc_object::rootAutorelease()
    └── id objc_object::rootAutorelease2()
        └── static id AutoreleasePoolPage::autorelease(id obj)
            └── static id AutoreleasePoolPage::autoreleaseFast(id obj)
                ├── id *add(id obj)
                ├── static id *autoreleaseFullPage(id obj, AutoreleasePoolPage *page)
                │   ├── AutoreleasePoolPage(AutoreleasePoolPage *newParent)
                │   └── id *add(id obj)
                └── static id *autoreleaseNoPage(id obj)
                    ├── AutoreleasePoolPage(AutoreleasePoolPage *newParent)
                    └── id *add(id obj)

在autorelease方法的调用栈中,最终都会调用上面提到的 autoreleaseFast方法,将当前对象加到AutoreleasePoolPage 中。

这一小节中这些方法的实现都非常容易,只是进行了一些参数上的检查,最终还要调用autoreleaseFast方法:

inline id objc_object::rootAutorelease() {
    if (isTaggedPointer()) return (id)this;
    if (prepareOptimizedReturn(ReturnAtPlus1)) return (id)this;

    return rootAutorelease2();
}

__attribute__((noinline,used)) id objc_object::rootAutorelease2() {
    return AutoreleasePoolPage::autorelease((id)this);
}

static inline id autorelease(id obj) {
   id *dest __unused = autoreleaseFast(obj);
   return obj;
}

autorelease函数和push函数一样,关键代码都是调用autoreleaseFast函数向自动释放池的链表栈中添加一个对象,
不过push函数的入栈的是一个边界对象,而autorelease函数入栈的是需要加入autoreleasepool的对象。

objc_autoreleasePoolPop

自动释放池释放是传入 push 返回的边界对象,

objc_autoreleasePoolPop(atautoreleasepoolobj);

然后将边界对象指向的这一页 AutoreleasePoolPage 内的对象释放
atautoreleasepoolobj就是返回的边界对象(POOL_BOUNDARY)

AutoreleasePoolPage::pop()实现:

static inline void pop(void *token)   // token指针指向栈顶的地址
{
    AutoreleasePoolPage *page;
    id *stop;

    page = pageForPointer(token);   // 通过栈顶的地址找到对应的page
    stop = (id *)token;
    if (DebugPoolAllocation  &&  *stop != POOL_SENTINEL) {
        // This check is not valid with DebugPoolAllocation off
        // after an autorelease with a pool page but no pool in place.
        _objc_fatal("invalid or prematurely-freed autorelease pool %p; ", 
                    token);
    }

    if (PrintPoolHiwat) printHiwat();   // 记录最高水位标记

    page->releaseUntil(stop);   // 从栈顶开始操作出栈,并向栈中的对象发送release消息,直到遇到第一个哨兵对象

    // memory: delete empty children
    // 删除空掉的节点
    if (DebugPoolAllocation  &&  page->empty()) {
        // special case: delete everything during page-per-pool debugging
        AutoreleasePoolPage *parent = page->parent;
        page->kill();
        setHotPage(parent);
    } else if (DebugMissingPools  &&  page->empty()  &&  !page->parent) {
        // special case: delete everything for pop(top) 
        // when debugging missing autorelease pools
        page->kill();
        setHotPage(nil);
    } 
    else if (page->child) {
        // hysteresis: keep one empty child if page is more than half full
        if (page->lessThanHalfFull()) {
            page->child->kill();
        }
        else if (page->child->child) {
            page->child->child->kill();
        }
    }
}

该过程主要分为两步:

  • page->releaseUntil(stop),对栈顶(page->next)到stop地址(POOL_SENTINEL)之间的所有对象调用objc_release(),进行引用计数减1
  • 清空page对象page->kill(),有两句注释
// hysteresis: keep one empty child if this page is more than half full

// special case: delete everything for pop(0)
除非是pop(0)方式调用,这样会清理掉所有page对象;
否则,在当前page存放的对象大于一半时,会保留一个空的子page,
这样估计是为了可能马上需要新建page节省创建page的开销。

小结

  • 自动释放池是一个个 AutoreleasePoolPage 组成的一个page是4096字节大小,每个 AutoreleasePoolPage 以双向链表连接起来形成一个自动释放池
  • 当对象调用 autorelease 方法时,会将对象加入 AutoreleasePoolPage 的栈中
  • pop 时是传入边界对象,然后对page 中的对象发送release 的消息

 

AutoReleasePool 底层原理 概念 AutoreleasePool(自动释放池)是OC中的一种内存自动回收机制,它可以延迟加入AutoreleasePool中的变量release的时机。在正常情况下,创建的变量会在超出其作用域的时候release,但是如果将变量加入AutoreleasePool,那么release将延迟执行。 App启动后,苹果在主线程 RunLoop里注册了两个 Observer,其回调都是 _wrapRunLoopWithAutoreleasePoolHandler(),从程序启动到加载完成,主线程对应的run 阅读详情

相关推荐

指数移动平均与一阶低通滤波:同一种算法,不同行业的叫法

在信号处理与数据分析中,平滑和滤波是绕不开的基础操作。指数移动平均(EMA)通过平滑系数对历史数据加权,越近的数据权重越大;一阶低通滤波则从频域视角衰减高频分量,其离散形式与EMA递推式完全等价。理解两者在数学本质上的统一,能帮助工程师在不同场景下灵活转换参数——无论是用截止频率还是平滑系数,都能快速调出理想的滤波效果。这种算法实现成本极低,只需一次乘加运算,在单片机、嵌入式系统、实时控制中广泛用于噪声抑制与信号平滑。同时,它也是深度学习优化器中动量项、卡尔曼滤波稳态解的基础原型。本文从概念到公式,再到工程

weixin_33827590的博客 531

autoreleasePool实现原理详解

在我们平时开发中,经常会涉及到对象的使用,但我们往往都不知道我们所开辟的对象是在何时被回收的,有没有及时的被释放,在苹果引入ARC之后,平时书写OC代码的时候都很少对内存释放做过处理,但是有一些场景还是需要我们手动去管理内存的释放;比如大量的for循环创建对象时候,比如子线程中存在持续性任务没办法及时关闭,这个时候也要我们手动管理临时变量的释放;

Chris.star的博客 1432

AutoreleasePool详解和runloop的关系

AutoreleasePool详解和runloop的关系内存管理一直是学习 Objective-C 的重点和难点之一,在实际的软件开发工作中,经常会遇见由于内存原因而导致的crash。而autorelease pool在内存管理中有着举足轻重的作用,只有理解了 autorelease pool 的原理,我们才算是真正了解了 Objective-C 的内存管理机制。下面我会从以下几个方面给大家讲解:

Mr_XiaoJie的博客 7527

@autoreleasepool自动释放池的底层实现原理

autoreleasepool是Objective-C中的一个关键字,用于创建自动释放池。自动释放池是一个内存管理机制,它用于管理在其范围内创建的对象的内存释放。在自动释放池的作用范围内创建的对象将在自动释放池被销毁时自动释放,而不需要手动调用release方法。自动释放池的主要作用是帮助开发人员管理内存,特别是在涉及大量临时对象的情况下,可以有效减少内存泄漏的风险。自动释放池通常在循环内部使用,以便在每次迭代后释放对象,从而避免内存过度增长。

good7ob的博客 678

COCOS学习笔记--内存管理(二)-PoolManager类和AutoreleasePool类的讲解

最近在看曹世博老师关于cocos引擎的学习教程,打算重新再系统梳理一下cocos相关的知识结构,学习之余把自己的一些收获和理解总结记录下来,方便日后自己回顾并同时希望本笔记可以对各位cocos学习者有所帮助,相关技术上博主理解如有偏颇,还请指正: 视频地址:http://edu.csdn.net/course/detail/1342/20985?auto_start=1   在上一篇博客:C

RapdoZoroの博客 3309

pix4d安装步骤

pix4d三维模型软件的安装步骤

Little_Bee_27000的博客 1万+

Autoreleasepool的理解及原理

Autoreleasepool的理解及原理之前师父问我对autoreleasepool有什么理解?当时的并没有研究过autoreleasepool,只知道在程序启动时会建立一个autoreleasepool,但不清楚autoreleasepool运行的原理。那么今天就来总结一波。接下来将从以下几个问题出发

爱生活的小悦悦的博客 2045

Abaqus中Cohesive单元建模:从本构到失效的完整指南

本文提供了Abaqus中Cohesive单元建模的完整指南,涵盖从本构模型到失效分析的全过程。详细解析了Cohesive单元作为模拟界面粘结与失效的关键工具,其核心在于弹性本构、损伤起始准则和损伤演化定律的设置。文章通过双悬臂梁(DCB)实例,手把手指导前处理、材料定义、求解设置及后处理分析,并分享了刚度、强度、断裂能等关键参数的影响与收敛性调优的实用避坑技巧,帮助用户准确模拟复合材料及胶接结构的界面失效行为。

cuda7parallel的博客 700

AutoreleasePool 的理解

转载出处:http://www.cocoachina.com/ios/20141031/10107.html  原作者:孙源 我是前言 Autorelease机制是iOS开发者管理对象内存的好伙伴,MRC中,调用[obj autorelease]来延迟内存的释放是一件简单自然的事,ARC下,我们甚至可以完全不知道Autorelease就能管理好内存。而在这背后,objc和编译器都帮我们

samuelandkevin的专栏 2460

Intouch间接变量(扩展)

间接变量只是Intouch提供给开发者的便捷方式之一,并不是所有情况都一定要使用间接变量,有时候用条件语句或者内存变量的方式也能起到类似的作用。

weixin_41571357的博客 2168

冰河木马实验(V8.4)

简述: 百科词条 冰河木马开发于1999年,跟灰鸽子类似,在设计之初,开发者的本意是编写一个功能强大的远程控制软件。但一经推出,就依靠其强大的功能成为了黑客们发动入侵的工具,并结束了国外木马一统天下的局面,跟后来的灰鸽子等等成为国产木马的标志和代名词。 冰河的服务器端程序为G-server.exe,客户端程序为G-client.exe,默认连接端口为7626。其中攻击者使用G-client.e...

野原新之助 1万+

关于对iOS中自动释放池autoreleasepool的一些理解

因为现在大家都在使用ARC模式下进行编程,一个很重要的问题也是最容易被大家所忽视的问题就是自动释放池,大部分程序员尤其是刚入行的都只是知道有这么一个东西,但具体是什么,工作的原理是什么,在什么时候使用它都一概不知。所以写一篇文章,记录一下个人对自动释放池的一些理解。 我们新建一个OC项目,在main函数中可以看到这么一串代码: int main(int argc, char * argv[])...

Horson19的博客 500

Python爬虫实战:亚马逊中国模拟登录与二次验证全解析(2026最新版)

在数据驱动的商业时代,亚马逊作为全球最大的电商平台,其商品数据、价格波动、评论信息、库存状态等对市场分析、竞品研究、价格监控具有极高的价值。然而,亚马逊的反爬虫机制堪称行业标杆——从请求指纹校验、动态令牌、行为分析到二次验证(2FA),层层设防。本篇文章将带你从零开始,使用2026年最新的Python技术栈,完整实现亚马逊中国(z.cn)的模拟登录,并攻克二次验证难题。郑重声明:本文仅限技术研究与个人学习用途,严禁用于批量抓取、价格劫持、账户爆破等违法违规行为。

2201_76125261的博客 377

STM32 I2C寄存器详解:从SR1调试卡死到主收发流程

I2C总线是嵌入式系统中连接传感器、EEPROM等外设的常用通信协议,其稳定运行高度依赖对底层寄存器的理解。寄存器作为硬件状态与控制的核心映射,直接决定了开发者能否高效定位通信异常。以STM32为例,CR1、CR2负责产生起始停止条件与配置时钟,SR1、SR2则实时反映总线状态、应答失败、字节传输等关键信息。当遇到总线卡死或ACK异常时,通过读取SR1标志位即可快速锁定病因,避免盲目猜测。掌握寄存器操作不仅有助于摆脱对库函数的黑盒依赖,还能在时钟配置、主收发流程设计中实现更精准的时序控制。本文从寄存器位定义

weixin_33895475的博客 432

【Halcon-1D测量】measure_pairs 函数功能(用于提取垂直于矩形/环形弧主轴的直边对)

HALCON算子measure_pairs是1D测量模块的基础工具,专用于提取垂直于矩形/环形弧主轴的直边对。该算子通过振幅阈值和灰度过渡规则(如positive/negative)进行边对分组,支持_strongest后缀选择最强边缘避免误配对。输出包含边缘坐标、振幅及内外间距(IntraDistance/InterDistance)。关键限制包括仅适用于直边、Sigma需≤0.5×测量长度,且忽略图像域。相比模糊版本算子,它更适用于边缘清晰的简单场景(如电子元件间距测量)。典型应用需配合gen_meas

weixin_45590420的博客 303

代谢组数据分析(二十一):通过MetaboAnalystR标准化构建sPLSDA预测模型

本文介绍了如何使用R语言中的MetaboAnalystR包和mixOmics包进行代谢组学数据的标准化和sPLSDA分析。MetaboAnalystR包用于数据预处理,包括数据初始化、清洗、补足、过滤和标准化等步骤,以确保数据质量。mixOmics包则用于sPLSDA分析,通过Lasso惩罚进行变量选择,并建立分类模型。文章详细说明了安装和加载相关R包的步骤,并提供了数据导入和预处理的代码示例。最后,强调了数据预处理的重要性,以确保后续分析的准确性和可靠性。

专注生信领域 2426

NSRunloop,runloop,autoReleasePool和thread的关系理解

NSRunloop NSRunloop顾名思义,就是一个消息循环,它会侦测输入源(input source)和定时源(timer source),然后做回调处理。这和windows的消息处理非常类似,只不过你无法看到类似SendMessage,PostMessage,GetMessage的方法,NSRunloop已经封装了这些细节。那NSRunloop的好处是不是只有封装细节,然后方便调用呢?答

zyy的专栏 5299

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

iOS中autoreleasepool的理解和使用

关于@autoreleasepool自动释放池block,苹果官方文档:Using Autorelease Pool Blocks面试经常会有这样的问题: 1.什么是@autoreleasepool? 2.里面对象的内存什么时候释放? 3.什么时候要用@autoreleasepool?回答: 1.@autoreleasepool是自动释放池,让我们更自由的管理内存2.当我们手动创建了一个@a

张少侠 1万+

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

autoreleasepool 的理解与使用

关于@autoreleasepool 自动释放池block,苹果官方文档:Using Autorelease Pool Blocks 面试经常会有这样的问题:  什么是@autoreleasepool?  里面对象的内存什么时候释放?  什么时候要用@autoreleasepool? 回答:  1.@autoreleasepool是自动释放池,让我们更自由的管理内存 2.当我们手动创建...

baihailing的博客 503

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Objective-C autoreleasepool深入理解

Objective-C autorelease // main.m int main(int argc, char * argv[]) { @autoreleasepool { } }    clang -rewrite-objc main.m __AtAutoreleasePool __autorelea...

weixin_30607029的博客 262

Runloop、autoreleasepool的简单理解

1. Runloop runloop是一种消息循环机制,每一个线程内部都有一个消息循环 只有主线程消息循环默认开启,子线程的消息循环默认不开启 1.1 Runloop的目的 保证程序不退出; 负责处理输入事件; 如果没有事件发生,会让程序进入休眠状态。 1.2 事件类型 Input Sources输入源 & Timer Source定时源; 输入源可以是键盘鼠标;定时源是...

weixin_30547797的博客 106

autoreleasepool 自动释放池的理解

常见的面试题:以下代码存在什么样的问题?应该如何改进? for (int i = 0; i < 100000; i++) { NSString *str = @"abc"; str = [str stringByAppendingString:@"xyz"]; } ...

weixin_30404405的博客 94

NSRunloop,runloop,autoReleasePool和thread的关系理解及案例解决

1.NSRunloop NSRunloop顾名思义,就是一个消息循环,它会侦测输入源(input source)和定时源(timer source),然后做回调处理。这和windows的消息处理非常类似,只不过你无法看到类似SendMessage,PostMessage,GetMessage的方法,NSRunloop已经封装了这些细节。那NSRunloop的好处是不是只有封装细节,然后方便调

冷小G的技术博客 3454

AutoreleasePool简记

相关资料: 自动释放池的前世今生 Objective-C Autorelease Pool 的实现原理 AutoreleasePool是什么,有什么用? 自动释放池,一个无需手动释放内存的对象指针存储池 实现这样的存储池有什么要素? 可伸缩的存储空间 能获取的存储空间边界的方式 AutoreleasePool支持嵌套:所以每个存储空间内需要记忆嵌套的存储

iOSiri的博客 736
上一篇: Category为什么不能添加属性
下一篇: 自旋锁 互斥锁 读写锁 递归锁
LIN1986LIN
博客等级 码龄19年 17粉丝 93原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值