在Objective-C中,AutoreleasePool是由NSAutoreleasePool类实现的。它使用了一个栈结构来管理自动释放池的创建和销毁。
AutoreleasePool的实现原理如下:
-
创建AutoreleasePool:在每个run loop迭代开始之前,会创建一个新的AutoreleasePool对象,通过调用
NSAutoreleasePool
的new
方法来创建。 -
添加对象:当一个对象调用
autorelease
方法时,该对象会被添加到当前的AutoreleasePool中。添加的方式是将对象放入AutoreleasePool的栈顶元素(innermost pool)中。 -
销毁AutoreleasePool:当一个AutoreleasePool的作用域结束时,它会被销毁。销毁操作会依次向栈中的每个AutoreleasePool发送一条
drain
消息。 -
释放对象:在AutoreleasePool被销毁时,会向其中的每个对象发送一条
release
消息,从而释放这些对象。这个过程是通过遍历栈中的每个AutoreleasePool来完成的。
需要注意的是,每个AutoreleasePool对象实际上是一个链表结构,它们通过一个指针串联起来。当一个AutoreleasePool被销毁时,会向它所包含的每个对象发送release
消息,并将这些对象从内存中释放。同时,被释放的AutoreleasePool会从链表中移除,下一个AutoreleasePool成为当前的栈顶元素。
AutoreleasePool的实现使得我们可以更方便地使用自动释放对象,避免手动管理内存的繁琐工作。它在开发中广泛应用于处理临时对象,减少内存占用和提高性能。
autoreleasePool实现原理详解_autoreleasepool原理-CSDN博客
[iOS] AutoreleasePool实现原理 - 简书
一个autorealese对象在什么时刻释放?
-
在AutoreleasePool的作用域结束时:当一个AutoreleasePool的作用域结束时,它会被销毁,此时会向其中的每个对象发送一条
release
消息,从而释放这些对象。 -
在run loop迭代结束时:在每个run loop迭代结束时,当前的AutoreleasePool会被销毁,此时会向其中的每个对象发送一条
release
消息,从而释放这些对象。 -
在手动调用
drain
方法时:除了自动释放池的作用域结束或run loop迭代结束外,还可以通过手动调用drain
方法来释放autorelease对象。drain
方法会立即销毁当前的AutoreleasePool,并向其中的每个对象发送一条release
消息。
需要注意的是,AutoreleasePool的释放仅仅是将对象发送一条release
消息,并不是立即释放对象。实际的内存释放会在稍后的某个时刻进行,具体的时机取决于系统的内存管理策略和autorelease对象的引用计数情况。
在ARC(Automatic Reference Counting)环境下,编译器会自动在适当的位置插入autorelease操作,以确保对象在合适的时机被释放。在MRC(Manual Reference Counting)环境下,需要手动调用autorelease
方法来添加对象到AutoreleasePool中,并在适当的时机手动调用release
方法来释放对象。
Autorelease对象在Autorelease Pool被释放的时刻释放。
在Objective-C或者Swift语言中,Autorelease Pool是用来管理autorelease对象的。当你创建一个autorelease对象时,它会被添加到最近创建的Autorelease Pool中。
Autorelease Pool是以堆栈的方式来组织的,也就是说,最新创建的Autorelease Pool会在最顶部,当你创建一个autorelease对象时,它会被添加到栈顶的Autorelease Pool中。当Autorelease Pool被释放(或者 drain)时,它会释放池中的所有对象。
在iOS或者OS X的应用程序中,每次事件循环(也就是Runloop)开始时,系统会自动创建一个新的Autorelease Pool,然后在事件循环结束时,自动释放这个Autorelease Pool。因此,autorelease对象通常会在事件循环结束时被释放。
如果你在一个新的线程中创建autorelease对象,你需要手动创建和释放Autorelease Pool。否则,这些autorelease对象可能无法正确释放。
一个autorelease对象可以被添加到多个Autorelease Pool中,只有当这个对象从所有的Autorelease Pool中移除时,它才会被释放。这是通过引用计数来实现的,每次将对象添加到Autorelease Pool时,它的引用计数会增加1,每次从Autorelease Pool中移除时,引用计数会减少1,只有当引用计数变为0时,对象才会被释放。
iOS基础知识5_自定义的 nsoperation 和 nsthread 需要手动创建自动释放池-CSDN博客
iOS面试题:一个 autorealese 对象在什么时刻释放? - 简书