https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html#//apple_ref/doc/uid/20000047-CJBFBEDI

Using Autorelease Pool Blocks

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 {
    // 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.

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.

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:

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

  • 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.

  • 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.

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

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.

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 retainmessage to the object within the block and then send it autorelease after the block, as illustrated in this example:

– (id)findMatchingObject:(id)anObject {
 
    id match;
    while (match == nil) {
        @autoreleasepool {
 
            /* Do a search that creates a lot of temporary objects. */
            match = [self expensiveSearchForObject:anObject];
 
            if (match != nil) {
                [match retain]; /* Keep match around. */
            }
        }
    }
 
    return [match autorelease];   /* Let match go and return it. */
}

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

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.

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.

Note: If you create secondary threads using the POSIX thread APIs instead of NSThread, 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 the NSThread class method isMultiThreaded.

Using Autorelease Pool Blocks的更多相关文章

  1. Autorelease pool

    根据苹果官方文档中对 Using Autorelease Pool Blocks 的描述,我们知道在下面三种情况下是需要我们手动添加 autoreleasepool 的: 如果你编写的程序不是基于 U ...

  2. Objective-C Autorelease Pool 的实现原理

    内存管理一直是学习 Objective-C 的重点和难点之一,尽管现在已经是 ARC 时代了,但是了解 Objective-C 的内存管理机制仍然是十分必要的.其中,弄清楚 autorelease 的 ...

  3. 【引】objective-c,6:Autorelease Pool

    参考博客: http://blog.leichunfeng.com/blog/2015/05/31/objective-c-autorelease-pool-implementation-princi ...

  4. 黑马程序员-autorelease pool

    Autorelease:可以延迟给对象发送release消息.发送一个autorelease消息给对象,证明该对象在一定时间内有效,一定时间后会对该对象进行释放,进行一次release. 一个auto ...

  5. RunLoop总结:RunLoop 与GCD 、Autorelease Pool之间的关系

    如果在面试中问到RunLoop相关的知识,很有可能也会问到RunLoop与GCD.Autorelease Pool有没有关系,哪些地方用到了GCD.Autorelease Pool等. So,本文就总 ...

  6. objective-C 的内存管理之-自动释放池(autorelease pool)

    如果一个对象的生命周期显而易见,很容易就知道什么时候该new一个对象,什么时候不再需要使用,这种情况下,直接用手动的retain和release来判定其生死足矣.但是有些时候,想知道某个对象在什么时候 ...

  7. 什么时候应该使用Autorelease Pool

    csdn首发:http://blog.csdn.net/guijiewan/article/details/46470285 Objective c使用ARC之后,一般都不需要再手动调用retain, ...

  8. ios学习笔记

    1.对于autorelease的理解 Each thread in a Cocoa application maintains its own stack of autorelease pool bl ...

  9. ios专题 -内存管理 研究

    [原创]http://www.cnblogs.com/luoguoqiang1985 ARC [新的规则] 1. you cannot explicitly invoke dealloc, or im ...

随机推荐

  1. HDP3.1 中 YRAN 和 MR2 的内存大小配置的计算方式

    Container 是 YARN 中基本的处理单元,它是对内存.CPU等计算的封装.总的来说,每个core每块硬盘 分配2个 container,能获得较好的集群利用率. 1. 确定可用内存大小. 对 ...

  2. 洛谷P1038 神经网络

    P1038 神经网络 题目背景 人工神经网络(Artificial Neural Network)是一种新兴的具有自我学习能力的计算系统,在模式识别.函数逼近及贷款风险评估等诸多领域有广泛的应用.对神 ...

  3. [Xcode 实际操作]三、视图控制器-(10)在Storyboard中使用图像视图控件

    目录:[Swift]Xcode实际操作 本文将演示常用的图像视图控件在故事板中的使用. 打开故事板文件[Main.storyboard]点击选择视图控制器的根视图. 点击库图标,打开控件库面板. 在控 ...

  4. python urllib2介绍

    urllib2是Python的一个获取URLs(Uniform Resource Locators)的组件.他以urlopen函数的形式提供了一个非常简单的接口, 这是具有利用不同协议获取URLs的能 ...

  5. 面试d090305知识点准备01

    1.1  类成员访问[jL1] 权限 1.2  写个双线程,计算50内的奇偶数 1.3  打印等腰三角形 1.4  运算符优先级 括号,非正负和自增减(右到左),乘除加减,等于不等于,逻辑与和或,然后 ...

  6. 如何在手机项目中使用rem单位

    rem这是个低调的css单位,近一两年开始崭露头角,有许多同学对rem的评价不一,有的在尝试使用,有的在使用过程中遇到坑就弃用了.但是我对rem综合评价是用来做web app它绝对是最合适的人选之一. ...

  7. GUI的最终选择 Tkinter(三):Checkbutton组件和Radiobutton组件、LabelFrame组件

    Checkbutton组件 Checkbutton组件就是常见的多选按钮,而Radiobutton则是单选按钮 from tkinter import * root = Tk() v = IntVar ...

  8. jquery——下载、使用

    jQuery是目前使用最广泛的javascript函数库. 怎样安装? 这是下载地址:https://code.jquery.com/ minified是压缩版的 新建一个网页打开上面这个网址,ctr ...

  9. 013 Roman to Integer 罗马数字转整数

    给定一个罗马数字,将其转换成整数. 返回的结果要求在 1 到 3999 的范围内. 详见:https://leetcode.com/problems/roman-to-integer/descript ...

  10. 010 Regular Expression Matching 正则表达式匹配

    Implement regular expression matching with support for '.' and '*'.'.' Matches any single character. ...