NSAutoreleasePool
一个支持cocoa
的采用引用计数的内存管理系统。
概述
当一个autorelease pool
本身被drain
时,autorelease pool
存储的对象将被发送一个release
消息。
如果您使用自动引用计数(ARC),您就不能直接使用autorelease pools
。相反,您应该使用@autoreleasepool
块。例如:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// Code benefitting from a local autorelease pool.
[pool release];
你应该写为:
@autoreleasepool {
// Code benefitting from a local autorelease pool.
}
@autoreleasepool
块比直接使用NSAutoreleasePool
实例更有效;即使你不使用ARC,你也可以使用它们。
在一个引用计数的环境中(相对于使用垃圾回收的环境),一个NSAutoreleasePool
对象包含接收到这些来自对象的 对象
autorelease
消息 和 当他drain
时的release
消息 。
但如果在销毁它时触发的是autorelease
方法, 那这个object就进入了对应的autorelease pool
, 它的生命就被延长了(当pool drain时才真正被销毁). 一个对象可以放在相同的释放池多次,在这种情况下它接收到的释放消息也会放在释放池中。
在引用计数的环境中,Cocoa
期望有一个可以随时可用的自动释放池。如果autorelease
不可用,则自动释放的对象不会被释放,会造成内存泄露。在这种情况下,您的程序通常会记录适当的警告消息。
应用程序包在事件循环的每一个循环开始时在主线程上创建一个自动释放池,并在结束时将其耗尽,从而释放在处理事件时生成的任何自动释放的对象。如果您使用的是应用程序包,那么您通常不需要创建自己的自动释放池。如果您的应用程序在事件循环中创建了许多临时的自动回调对象,那么创建“本地”自动释放池将有助于最小化峰值内存占用。
您可以使用通常的alloc和init
消息创建一个NSAutoreleasePool
对象,并通过drain
(或release)
将其处理掉。因为您不能retain
(或autorelease
)一个自动释放池,当drain
一个自动释放池最终会产生回收的效果。
您应该总是在相同的上下文中(调用方法或函数,或者循环的主体)在相同的环境中耗尽一个自动释放池。请参阅使用Autorelease Pool Blocks
获得更多详细信息。
每个线程(包括主线程)都维护自己的NSAutoreleasePool
对象堆栈(参见Threads
)。当创建新的pool
时,它们会被添加到堆栈的顶部。当pool
被释放时,它们被从堆栈中删除。自动释放的对象被放置到当前线程的顶部自动释放池中。当一个线程终止时,它会自动地耗尽与自身相关的所有自动释放池。
Threads
如果您正在应用程序包的主线线程之外进行Cocoa
调用,比如说,您创建了一个仅用于创建基础的应用程序,或者如果您分离了一个线程,那么您需要创建自己的自动释放池。
如果您的应用程序或线程是长期存在的,并且有可能生成大量自动释放的对象,那么您应该定期地消耗并创建自动释放池(就像应用程序包在主线程上所做的那样);否则,自动解除的对象会累积,内存占用也会增加。但是,如果您的分离线程不进行Cocoa
调用,那么您就不需要创建一个自动释放池。
如果您正在使用POSIX线程api而不是NSThread对象创建辅助线程,那么您就不能使用Cocoa,包括NSAutoreleasePool,除非Cocoa处于多线程模式中。只有在分离了第一个NSThread对象之后,Cocoa才进入多线程模式。要在二级POSIX线程上使用Cocoa,应用程序必须首先分离至少一个NSThread对象,该对象可以立即退出。您可以使用NSThread类方法测试Cocoa是否处于多线程模式中
Garbage Collection(垃圾回收机制)
在垃圾收集的环境中,不需要自动的池。但是,您可以编写一个框架,该框架设计的目的是用于在垃圾收集和引用计数环境中工作。在这种情况下,您可以使用autorelease poo
l来提示收集器,收集可能是适当的。在垃圾收集的环境中,如果需要的话,发送drain
消息到autorelease pool
会触发垃圾收集; 而使用release
,这是一种无效的操作。在采用引用计数的环境中,drain
和release有
相同的效果,因此,通常,您应该使用drain而不是release
。
本人英文不好,希望大家勉强凑合看。
官方说明:https://developer.apple.com/documentation/foundation/nsautoreleasepool