Autorelease && Autorelease Pool && Runloop

之所以将这三个东西放到一起说,主要是由于息息相关,互相影响,互相依赖。

Autorelease

What:是一种支持引用技术的内存管理方式。使被标示autorelease的对象在可以被销毁的时候放入最近的(栈顶的)释放池,等待释放。是一种延时释放,提高系统性能。

When:在没有手加autorelease pool的情况下,autorelease对象是在当前的runloop迭代结束时释放的,而它能够释放的原因是系统在每个runloop迭代中都加入了自动释放池Push和Pop。(autorelease并不是根据作用域来决定释放时机的,而是依据runloop来决定释放时机的。)

Where:ARC下就加在可以自动添加autorelease的对象被创建出来的时候。

Why:OC的内存管理机制中比较重要的一条规律是:谁申请,谁释放。考虑这种情况,如果一个方法需要返回一个新建的对象,该对象何时释放?方法内部是不会写release来释放对象的,因为这样做会将对象立即释放而返回一个空对象;调用者也不会主动释放该对象的,因为调用者遵循“谁申请,谁释放”的原则。那么这个时候,就发生了内存泄露。针对这种情况,Objective-C的设计了autorelease,既能确保对象能正确释放,又能返回有效的对象。

在autorelease的模式下,代码如下:

ClassA *Func1()
{
ClassA *obj = [[[ClassA alloc]init]autorelease];
return obj;
}

Autorelease Pool

What:是OC的一种内存自动回收机制,可以将一些临时变量通过自动释放池来回收统一释放。自动释放池本身销毁的时候,池子里面所有的对象都会做一次release操作。

自动释放池以栈的形式实现:当你创建一个新的自动释放池时,它将被添加到栈顶。接收autorelease消息的对象将被放入到最顶端的自动释放池中。如果将一个对象放入一个自动释放池中,然后创建一个新的自动释放池再销毁该新建的自动释放池,则这个自动释放对象仍将存在,因为容纳该对象的自动释放池仍然存在。

When: 当出了@autoreleasepool{ ··· }的作用域时,当前autoreleasepool被drain。所有的release pool会构成一个像CallStack一样的一个栈式结构,在每一个Runloop结束时,当前栈顶的autorelease pool会被销毁,这样这个pool里的每个Object会被release。

黄金法则:如果对一个对象使用了alloc、[mutable]copy、retain,那么必须使用相应的release或者autorelease。ARC下autorelease被自动添加。

Why:见autorelease,原因相同。

注意:在主线程的 NSRunLoop 对象(在系统级别的其他线程中应该也是如此,比如通过 dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) 获取到的线程)的每个 event loop 开始前,系统会自动创建一个 autoreleasepool,并在event loop结束时drain。另外,NSAutoreleasePool 中还提到,每一个线程都会维护自己的 autoreleasepool 堆栈。换句话说 autoreleasepool 是与线程紧密相关的,每一个 autoreleasepool 堆栈只对应一个线程。

Runloop

What:轮训,在线程中不停地对事件进行观察,做出响应,其余内容暂不讨论。

其他:

在iOS中有三种常用的遍历方法:for、forin、enumerateObjectsUsingBlcok;block版本的遍历方式已经内嵌了@autoreleasepool{}操作,而前面两个没有,这样就意味着使用block版本的遍历方式会使app更加健壮,内存使用效率更加出色。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,506评论 30 472
  • 一、什么是runloop 字面意思是“消息循环、运行循环”。它不是线程,但它和线程息息相关。一般来讲,一个线程一次...
    WeiHing阅读 8,293评论 11 111
  • 37.cocoa内存管理规则 1)当你使用new,alloc或copy方法创建一个对象时,该对象的保留计数器值为1...
    如风家的秘密阅读 947评论 0 4
  • 11.看下面的程序,第一个NSLog会输出什么?这时str的retainCount是多少?第二个和第三个呢? 为什...
    AlanGe阅读 820评论 1 4
  • 1、[NSObject alloc]在创建完对象后,会让该对象的retainCount+1,后续的init为初始化...
    naiyi阅读 1,638评论 0 4

友情链接更多精彩内容