Using Autorelease Pool Blocks
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的更多相关文章
- Autorelease pool
根据苹果官方文档中对 Using Autorelease Pool Blocks 的描述,我们知道在下面三种情况下是需要我们手动添加 autoreleasepool 的: 如果你编写的程序不是基于 U ...
- Objective-C Autorelease Pool 的实现原理
内存管理一直是学习 Objective-C 的重点和难点之一,尽管现在已经是 ARC 时代了,但是了解 Objective-C 的内存管理机制仍然是十分必要的.其中,弄清楚 autorelease 的 ...
- 【引】objective-c,6:Autorelease Pool
参考博客: http://blog.leichunfeng.com/blog/2015/05/31/objective-c-autorelease-pool-implementation-princi ...
- 黑马程序员-autorelease pool
Autorelease:可以延迟给对象发送release消息.发送一个autorelease消息给对象,证明该对象在一定时间内有效,一定时间后会对该对象进行释放,进行一次release. 一个auto ...
- RunLoop总结:RunLoop 与GCD 、Autorelease Pool之间的关系
如果在面试中问到RunLoop相关的知识,很有可能也会问到RunLoop与GCD.Autorelease Pool有没有关系,哪些地方用到了GCD.Autorelease Pool等. So,本文就总 ...
- objective-C 的内存管理之-自动释放池(autorelease pool)
如果一个对象的生命周期显而易见,很容易就知道什么时候该new一个对象,什么时候不再需要使用,这种情况下,直接用手动的retain和release来判定其生死足矣.但是有些时候,想知道某个对象在什么时候 ...
- 什么时候应该使用Autorelease Pool
csdn首发:http://blog.csdn.net/guijiewan/article/details/46470285 Objective c使用ARC之后,一般都不需要再手动调用retain, ...
- ios学习笔记
1.对于autorelease的理解 Each thread in a Cocoa application maintains its own stack of autorelease pool bl ...
- ios专题 -内存管理 研究
[原创]http://www.cnblogs.com/luoguoqiang1985 ARC [新的规则] 1. you cannot explicitly invoke dealloc, or im ...
随机推荐
- [转]centos7.2 下 nginx 开机启动
1.在系统服务目录里创建nginx.service文件 vi /lib/systemd/system/nginx.service 内容如下 [Unit] Description=nginx After ...
- 线程池、Lambda表达式
线程池.Lambda表达式 线程池.Lambda表达式 线程池.Lambda表达式 线程池.Lambda表达式 线程池.Lambda表达式 线程池.Lambda表达式 线程池.Lambda表达式 (正 ...
- HDU1272-小希迷宫
题目链接:点击打开链接 Problem Description 上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走.但是她设计迷宫的思路不一样,首 ...
- 11-散列4 Hashing - Hard Version (30 分)
Given a hash table of size N, we can define a hash function (. Suppose that the linear probing is us ...
- Spring对数据库的操作
Spring结合Hibernate HibernateTemplate http://www.jb51.net/article/41541.htm //////// ...
- 源码分析String
hashCode 计算每个char值,并移位累加 计算后的hash值会缓存
- @Inherited:允许子类继承父类的注解。
在看定义注解的相关文章的时候,看到这个@Inherited注解,简单的说明并没有真正搞懂是什么意思.在网上搜索了一些相关的内容,现在把一篇文章转载过来.以便后面使用. 文章出处,转载地址:(http: ...
- DB2 触发器使用1
本文基于多篇博文整理而来,目的是较全面的学会使用DB2触发器,后期再整理复杂的使用场景,看完本文应该能够自己创建一个基本的触发器. 1.什么是触发器当一个指定的 SQL 操作(如 DELETE,INS ...
- 爬虫(AJEX)——豆瓣动态页面
工具:python3 解释:Ajax 是一种用于创建快速动态网页的技术,在无需重新加载整个网页的情况下,能够更新部分网页的技术. 目标:爬取使用Ajex结束的豆瓣网页 import urllib.re ...
- Vue 项目: npm run dev b报错 “'webpack-dev-server' 不是内部或外部命令,也不是可运行的程序 或批处理文件。”
前提: 电脑已经安装了nodeJS和npm, 项目是直接下载的zip包. 报错步骤为1:cd /d 目录: 2. npm ren dev -------> 报错如下: > webpac ...