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. 51nod1007(01背包)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1007 题意:中文题诶- 思路:尽量将一个数组分成两个相等的部 ...

  2. 关于CSRF攻击详解

    CSRF的原理以及防范 CSRF概念:CSRF跨站点请求伪造(Cross—Site Request Forgery),跟XSS攻击一样,存在巨大的危害性,你可以这样来理解: 攻击者盗用了你的身份,以你 ...

  3. has been blocked by CORS policy: Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response.

    https://www.cnblogs.com/caimuqing/p/6733405.html // TODO 支持跨域访问 response.setHeader("Access-Cont ...

  4. POJ3974 Palindrome Manacher 最长回文子串模板

    这道题可以$O(nlogn)$,当然也可以$O(n)$做啦$qwq$ $O(nlogn)$的思路是枚举每个回文中心,通过哈希预处理出前缀和后缀哈希值备用,然后二分回文串的长度,具体的就是判断在长度范围 ...

  5. AJAX (分页)

    <!-- 企业新闻列表开始,图尺寸550*310,如果没图,则在li上加on --> <div class="common-box new-box"> &l ...

  6. Hello ASP.NET on Docker -- CentOS

    1.docker pull microsoft/aspnet 2.docker run -p 5004:2015 microsoft/aspnet --穿越后 3.cd ~ && wg ...

  7. Python metaclasses

    metaclasses元类:就像对象是类的实例一样,类是它的元类的实例.调用元类可以创建类. metaclass使用type来创建类,type可以被继承生成新的元类. 这个和C#的反射很相似. 下面是 ...

  8. 白话SpringCloud | 第零章:前言

    说在前面 大清早醒来,觉得睡不着了.还是起来,写写博客.但最后发现关于SpringBoot的安全相关的还是比较多内容的,也比较专业,怕是一个多小时完不成的,也罢,那就来写写关于SpringCloud前 ...

  9. ASP Session的功能的缺陷以及解决方案

    转http://www.cnblogs.com/jhy55/p/3376925.html 目前ASP的开发人员都正在使用Session这一强大的功能,但是在他们使用的过程中却发现了ASP Sessio ...

  10. 关于Mdi窗口-父窗口上的控件把子窗口的挡住的问题

    using System.Runtime.InteropServices; [DllImport("user32")] public static extern int SetPa ...