iOS内存管理系列之二:自动释放与便捷方法
有时候一个所有者创建一个对象后,会立刻将该对象的指针传递给其它所有者。这时,这个创建者不希望再拥有这个对象,但如果立刻给它发送一个release消息会导致这个对象被立刻释放掉——这样其它所有者还没有来得及保留该对象。解决这个两难问题的方法是,给对象发送一个autorelease消息:这样创建者不再拥有该对象的所有权;该对象成为自动释放的对象,但是不会立刻被释放掉;其它所有者可以有时间保留或复制该对象,并成为其唯一所有者。
我们来看一个自动释放的例子(代码清单3-1)。一个所有者先用alloc方法创建一个对象;此时该所有者拥有这个对象,对象的引用计数为1。紧接着,所有者自动释放该对象;所有者此时已经放弃了所有权,但对象的引用计数在一段时间内依然为1。我们可以看出自动释放的另一个好处:你不会因为在后面忘记给对象发送release消息而造成内存泄露。
代码清单3-1
-(Object*)returnAutoreleaseObject {
Object* obj = [[Object alloc] init];
return [obj autorelease];
}
与自动释放相关的,有一大类构造方法(constructor method),由它们构造的对象直接就是自动释放的对象;这一类构造方法叫做便捷方法。比如下面这句的字符串就是一个自动释放的对象,stringWithFormat:就是一个便捷方法。
NSString* string = [NSString stringWithFormat:@”autoreleaseString”];
再举几个便捷方法的例子,方便读者以后的开发。
1.NSArray的arrayWithObjects:和arrayWithArray:。
2.UIImage的imageNamed:。
3.NSNumber的numberWithBool等。
现在我们已经解释了,autorelease方法会在一段时间以后释放掉一个对象,在这段时间内我们可以安全地使用该对象。那么这段时间究竟是多久呢?我们需要先更多地了解自动释放的机制,再来回答这个问题。
让我们先来看看自动释放池。自动释放池是NSAutoreleasePool的实例,其中包含了收到autorelease消息的对象。当一个自动释放池自身被销毁(dealloc)时,它会给池中每一个对象发送一个release消息(如果你给一个对象多次发送autorelease消息,那么当自动释放池销毁时,这个对象也会收到同样数目的release消息)。可以看出,一个自动释放的对象,它至少能够存活到自动释放池销毁的时候。
那么自动释放池何时被创建,又何时被销毁呢?在每一个事件周期(event cycle)的开始,系统会自动创建一个自动释放池;在每一个事件周期的结尾,系统会自动销毁这个自动释放池。一般情况下,你可以理解为:当你的代码在持续运行时,自动释放池是不会被销毁的,这段时间内你也可以安全地使用自动释放的对象;当你的代码运行告一段落,开始等待用户输入(或者其它事件)时,自动释放池就会被释放掉,池中的对象都会收到一个release消息,有的可能会因此被销毁。
到此为止,相信你已经对自动释放的机制有了一个大体的了解。自动释放而非直接释放,可以帮助你节省一些代码量,提高开发速度。但是它有一个直接的缺点:它延缓了对象的释放,在有大量自动释放的对象时,会占用大量内存资源。因此,你需要避免将大量对象自动释放。并且,在以下两种情况下,你需要手动建立并手动销毁掉自动释放池:
1.当你在主线程外开启其它线程时:系统只会在主线程中自动生成并销毁掉自动释放池。
2.当你在短时间内制造了大量自动释放对象时:及时地销毁有助于有效利用iPad上有限地内存资源。
iOS内存管理系列之二:自动释放与便捷方法的更多相关文章
- IOS内存管理「3」- 自动释放的基本概念和用法
- iOS内存管理系列之一:对象所有权与引用计数
当一个所有者(owner,其本身可以是任何一个Objective-C对象)做了以下某个动作时,它拥有对一个对象的所有权(ownership): 1. 创建一个对象.包括使用任何名称中包含“alloc” ...
- java执行程序的内存分析系列专栏二之static变量和方法内存分析
昨天写了简单的聊了下java执行程序时简单的内存划分,今天我们接着往下聊,聊聊static变量和方法的内存分析. 1.static变量和方法的第一个特性内存分析 statiic变量和方法的第一个特性能 ...
- ios内存管理笔记(二)
1)实现部分: 复制代码 @synthesize window=_window; @synthesize viewController=_viewController; 通常看到的都没有包含=部分,@ ...
- Delphi内存管理(Integer、Boolean、Record、枚举等都是在作用域内编译器自动申请内存,出了作用域自动释放;另外,字符串、Variant、动态数组、接口也是由Delphi自动管理)
一.什么是堆.栈? 程序需要的内存空间分为 heap(堆) 和 stack(栈),heap 是自由存储区, stack 是自动存储区,使用 heap 需要手动申请.手动释放, stack 是自动申请. ...
- 【Bugly干货分享】iOS内存管理:从MRC到ARC实践
Bugly 技术干货系列内容主要涉及移动开发方向,是由Bugly邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟撰写而成,内容均属原创,转载请标明出处. 对于iOS程序员来说,内存管理是入门的 ...
- iOS内存管理个人总结
一.变量,本质代表一段可以操作的内存,她使用方式无非就是内存符号化+数据类型 1.保存变量有三个区域: 1>静态存储区 2>stack 3>heap 2.变量又根据声明的位置有两种称 ...
- iOS内存管理编程指南
iOS 内存管理 目录[-] 一:基本原则 二:成员变量的内存管理 三:容器对象与内存管理 四:稀缺资源的管理 五:AutoRelease 六:其他注意事项 iOS下内存管理的基本思想就是引用计数,通 ...
- iOS 内存管理:从 MRC 到 ARC 实践
对于 iOS 程序员来说,内存管理是入门的必修课.引用计数.自动释放等概念,都是与 C 语言完全不同的. iOS 内存管理的核心是引用计数. 接触 MRC 时遇到最头疼的问题就是:为什么那么多 rel ...
随机推荐
- HDU2024JAVA
C语言合法标识符 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- Android(java)学习笔记179:BroadcastReceiver之 有序广播和无序广播(BroadcastReceiver优先级)
之前我们在Android(java)学习笔记178中自定义的广播是无序广播,下面我们要了解一下有序广播: 1. 我们首先了解一下有序广播和无序广播区别和联系? (1) 有序广播> 接受者 ...
- Linux文件查找命令find用法整理(locate/find)
Linux文件查找查找主要包括:locate和find 1.locate 用法简单,根据数据库查找,非实时,用法: locate FILENAME 手动更新数据库(时间可能较长) updatedb 2 ...
- 探索开发跨平台移动App,谈Jquery Mobile 和PhoneGap应用
随着智能手机等设备的大范围普及,各形各色的移动端软件随之既出.各互联网运营商也都在抢占移动软件的占有率.不惜采用财力进行宣传推广.例如,通过手机淘宝客户端购买物品总比pc端要便宜,360手机助手下载对 ...
- C# 事件的理解
说实话,事件弄得还是很晕,有待于以后的强化吧,下面是我对事件的一点理解 首先,参见大牛的帖子:网上大牛事件讲解 下面我来说一说事件的大致流程: 事件委托事件概述事件就是当对象或类状态发生改变时,对象或 ...
- ThinkPHP的数据库访问的简单操作
传统的sql与ThinkPHP中的sql相比较 以user表为例 $user=M('user'); 1: SELECT * FROM user----------$user->select( ...
- Jsp内置对象-session
session内置对象介绍 个人理解:session因为是唯一的, session是与请求有关的会话期,它是java.servlet.http.HttpSession类的对象,用来表示和存储当前页面的 ...
- CoreAnimation5-图层时间和缓冲
图层时间 动画的发生是需要持续一段时间的,所以计时对整个概念来说至关重要.在这一章中,我们来看看CAMediaTiming,看看Core Animation是如何跟踪时间的. CAMediaTimin ...
- 一看就懂ReactJS
现在最热门的前端框架有AngularJS.React.Bootstrap等.自从接触了ReactJS,ReactJs的虚拟DOM(Virtual DOM)和组件化的开发深深的吸引了我,下面来跟我一起领 ...
- Visual Studio 2008中添加运行按钮 转载
在Visual Studio 2008中添加运行按钮 默认情况下,VS2008中的工具栏上没有运行按钮,只有调试(Debug)按钮,可按照以下方法添加 1.点击菜单Tools(工具)->Cust ...