自动释放池三种使用情形

Autorelease pool blocks provide a mechanism whereby you can relinquish ownership of an object, but avoid the possibility of it being deallocated immediately (such as when you return an object from a method). Typically, you don’t need to create your own autorelease pool blocks, but there are some situations in which either you must or it is beneficial to do so.

自动释放池提供了一种机制,你可以放弃一个对象的所有权,但是又避免了立即释放对象,例如当你要从一个方法返回一个对象的时候。通常你不需要创建你自己的自动释放池。但是,有几种情况你必须创建或者创建后是有好处的。

About Autorelease Pool Blocks

关于自动释放池

An autorelease pool block is marked using@autoreleasepool, as illustrated in the following example:

自动释放池用@autoreleasepool,标识,像下边这样。

@autoreleasepool {

// Code that creates autoreleased objects.

}

At the end of the autorelease pool block, objects that received an autorelease message within the block are sent a release message—an object receives a release message for each time it was sent an autorelease message within the block.

在自动释放池的末尾,在block内部,那些收到autorelease消息的对象会被发送一条autorelease消息。在block内,每次那个收到autorelease消息的对象,也会收到release消息。

Like any other code block, autorelease pool blocks can be nested:

一些其他情况,自动释放池会进行嵌套。

@autoreleasepool {

// . . .

@autoreleasepool {

// . . .

}

. . .

}

(You wouldn’t normally see code exactly as above; typically code within an autorelease pool block in one source file would invoke code in another source file that is contained within another autorelease pool block.) For a given autorelease message, the corresponding release message is sent at the end of the autorelease pool block in which the autorelease message was sent.

(正常情况下,你不会显示的看到上边的代码,一般,在一个源文件的自动释放池会调用在另外一个含有自动释放池的源文件中调用)。对于一条给定的autorelease消息,相应的release消息会在发送autorelease消息的自动释放池的末尾进行发送。

Cocoa always expects code to be executed within an autorelease pool block, otherwise autoreleased objects do not get released and your application leaks memory. (If you send an autorelease message outside of an autorelease pool block, Cocoa logs a suitable error message.) The AppKit and UIKit frameworks process each event-loop iteration (such as a mouse down event or a tap) within an autorelease pool block. Therefore you typically do not have to create an autorelease pool block yourself, or even see the code that is used to create one. There are, however, three occasions when you might use your own autorelease pool blocks:

cocoa希望在自动释放池内执行代码,否则autoreleased的对象不能释放,你的程序会出现内存泄漏。如果你在自动释放池外部发送一条autorelease消息,cocoa会报错。AppKit 和 UIKit处理一些往复的事件循环在自动释放池中。像鼠标事件或者点击事件。因此你一般不需要自己创建自动释放池,或者甚至是看到用于创建自动释放池的代码。然而,有时候,三种场合下,你可能要创建自己的自动释放池。

1)If you are writing a program that is not based on a UI framework, such as a command-line tool.

如果你创建了一个不是基于UI框架的程序,例如命令行工具。

2)If you write a loop that creates many temporary objects.

如果你写了一个创建了很多临时变量的循环。

You may use an autorelease pool block inside the loop to dispose of those objects before the next iteration. Using an autorelease pool block in the loop helps to reduce the maximum memory footprint of the application.

你可能在下次循环之前使用一个自动释放池来释放那些变量。在循环中使用自动释放池来减少应用程序的峰值内存占用。

3)If you spawn a secondary thread.

如果你创建了一个二级线程。

You must create your own autorelease pool block as soon as the thread begins executing; otherwise, your application will leak objects. (See Autorelease Pool Blocks and Threads for details.)

你必须创建你的自动释放池在线程一开始执行的时候,否则,你的应用将会内存泄漏。

Use Local Autorelease Pool Blocks to Reduce Peak Memory Footprint。

使用自动释放池来减少峰值内存占用。

Many programs create temporary objects that are autoreleased. These objects add to the program’s memory footprint until the end of the block. In many situations, allowing temporary objects to accumulate until the end of the current event-loop iteration does not result in excessive overhead; in some situations, however, you may create a large number of temporary objects that add substantially to memory footprint and that you want to dispose of more quickly. In these latter cases, you can create your own autorelease pool block. At the end of the block, the temporary objects are released, which typically results in their deallocation thereby reducing the program’s memory footprint.

许多程序自动释放的临时对象。这些对象添加到程序的内存直到这个block结束。在大多数情况下,允许临时对象累计直到这个当前循环结束并不会引起内存占用大大占用。然而,在一些情况下,你可能会创建大量的临时对象,从而增加内存空间(这里的累计更多的是来不及释放)。你想要快速释放它们。在后边这种情况下,你可以创建自己的自动释放池。在自动释放池的最后,临时对象被release,这通常导致它们释放减少了内存占用。

The following example shows how you might use a local autorelease pool block in a for loop.

下边的例子显示在for循环中,你怎样利用自动释放池。

NSArray *urls = <# An array of file URLs #>;

for (NSURL *url in urls) {

@autoreleasepool {

NSError *error;

NSString *fileContents = [NSString stringWithContentsOfURL:url

encoding:NSUTF8StringEncoding error:&error];

/* Process the string, creating and autoreleasing more objects. */

}

}

The for loop processes one file at a time. Any object (such as fileContents) sent an autorelease message inside the autorelease pool block is released at the end of the block.

这个for循环移除处理一个文件夹。在block最后,自动释放池中的所有对象都会发送一条autorelease消息。

注意:用类方法创建的对象,一般会把这个对象放入最近的自动释放池中。这就导致for循环中大量的对象放入了自动释放池中。导致局部出现了内存释放。对于这种情况最好不要等到让系统的自动释放池一次释放,需要自己创建一个自动释放池,这样的话我们就可以把局部变量提前释放了。

After an autorelease pool block, you should regard any object that was autoreleased within the block as “disposed of.” Do not send a message to that object or return it to the invoker of your method. If you must use a temporary object beyond an autorelease pool block, you can do so by sending a retain message to the object within the block and then send it autorelease after the block, as illustrated in this example

经过一个自动释放池之后,你应该把autoreleased的所有对象都给释放掉。不要发送消息给那个对象或者返回它给你的方法的调用者。如果你必须用一个超出自动释放池的临时变量,你可以发送一条retain消息给这个对象,然后在自动释放池之后给他发送一条autorelease消息,像下边例子一样:

优化

Sending retain to match within the autorelease pool block the and sending autorelease to it after the autorelease pool block extends the life time of match and allows it to receive messages outside the loop and be returned to the invoker of findMatchingObject:.

在自动释放池中给match发送retain消息,在之后给match发送autorelease消息。这样允许他来接收循环之外的消息,并且可以作为返回参数。

Autorelease Pool Blocks and Threads

自动释放池和线程

Each thread in a Cocoa application maintains its own stack of autorelease pool blocks. If you are writing a Foundation-only program or if you detach a thread, you need to create your own autorelease pool block.

在cocoa程序中,每个线程都维护自己的自动释放池的栈结构。如果你正在写一个仅有Foundation的项目或者你分离线程,你需要自己的自动释放池。

If your application or thread is long-lived and potentially generates a lot of autoreleased objects, you should use autorelease pool blocks (like AppKit and UIKit do on the main thread); otherwise, autoreleased objects accumulate and your memory footprint grows. If your detached thread does not make Cocoa calls, you do not need to use an autorelease pool block.

如果你的程序或者线程长期存在,那么潜在的会存在大量的需要autoreleased的对象。你应该使用自动释放池,像AppKit 和 UIKit在主线程做的那样。否则,会堆积占用大量的内存。如果你的耳机线程不需要调用call,你不需要使用自动释放池。

Note:If you create secondary threads using the POSIX thread APIs instead o fNSThread, you cannot use Cocoa unless Cocoa is in multithreading mode. Cocoa enters multithreading mode only after detaching its first NSThread object. To use Cocoa on secondary POSIX threads, your application must first detach at least one NSThread object, which can immediately exit. You can test whether Cocoa is in multithreading mode with theNSThreadclass method isMultiThreaded.

注意:如果你用POSIX线程API创建了一个辅助线程,你不能使用cocoa。除非cocoa在多线程。cocoa只有在分离他的第一个线程对象之后。为了在辅助线程使用cocoa,你的程序必须分理出一个线程对象,这个线程对象可以立即停止。你可以检测cocoa是否处于多线程模式中。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,999评论 4 368
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,102评论 1 302
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,709评论 0 250
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,439评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,846评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,881评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,062评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,783评论 0 205
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,517评论 1 248
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,762评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,241评论 1 264
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,568评论 3 260
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,236评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,145评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,941评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,965评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,802评论 2 275

推荐阅读更多精彩内容