登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

vs-yanguo的博客

 
 
 

日志

 
 
 
 

iOS内存管理系列之二:自动释放与便捷方法  

2010-11-05 17:48:56|  分类: objective c |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |


—–自动释放(Auto release)与便捷方法(convenience method)—– 有时候一个所有者创建一个对象后,会立刻将该对象的指针传递给其它所有者。这时,这个创建者不希望再拥有这个对象,但如果立刻给它发送一个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上有限地内存资源。


内存管理是iPhone或iPad开发中最为重要的一部分。掌握好了内存管理,开发出的应用就能运行流畅;掌握不好,开发出的东西就会效率低下,且容易崩溃。从本文开始,我将分几次详细介绍iOS内存管理的方方面面,包括对象的所有权与引用计数、自动释放与便捷方法、访问器方法与属性、一些会改变引用计数的特殊情况、以及一个总结。希望这些介绍会对开发者有所帮助。 本系列文章版权归李晨所有,出版权归华章公司所有,谢绝转载。 -----对象所有权(ownership)与引用计数(retain count、reference count)----- 当一个所有者(owner,其本身可以是任何一个Objective-C对象)做了以下某个动作时,它拥有对一个对象的所有权(ownership): 1. 创建一个对象。包括使用任何名称中包含“alloc”、“new”、或者“copy”的方法。 2. 保留(retain)一个对象。 一个对象可以有多个所有者,一个所有者也可以拥有多个对象。 相应的,引用计数增减的基本规则是: 1.当所有者创建一个对象时,该对象的引用计数为1。 2.当所有者保留它时,该对象的引用计数加1。 3.当所有者释放(release)它时,该对象的引用计数减1。 与此相关的,当一个所有者对于一个对象的引用计数的增减总计为0时,它放弃了对这个对象的所有权。 现在我们可以从两个不同的角度来看Objective-C的内存管理问题。从对象所有权的角度来看,当一个对象有着至少一个所有者(owner)的时候,它依然存在;当它没有任何所有者的时候,它会被释放掉。从引用计数的角度看,一个对象存在时,其引用计数大于零;当一个对象的引用计数为零时,它会调用dealloc方法并释放掉。这两个角度的关系是:在所有权的背后起作用的机制是引用计数机制;我们通过引用计数的增减来理解所有权的概念;但是你只应当使用所有权的概念来管理内存,因为如果你试图直接获取对象的引用计数,那么得到的数将让你感到匪夷所思——系统的一些框架会“偷偷”增减对象的引用计数。 回顾一下,内存管理的目标是:当一个对象的某个所有者依然需要使用它时,保证这个对象的存在;当一个对象的所有所有者都不再需要它时,保证这个对象被销毁。因此只要任何一个所有者在使用完一个对象之后释放掉它,那么以上内存管理的目标就可以实现。我们可以得出任何一个所有者(记住,所有者本身也只是一个对象)所应当遵守的基本步骤: 拥有一个对象 -> 使用一个对象 -> 放弃对象的所有权。 从引用计数的角度来看就是: 还需要这个对象时,保持对其增减为正;不再需要这个对象时,保持对其增减为0。 下图很好地诠释了这些基本规则:所有者1和所有者2单独地执行了拥有对象、使用对象、放弃对象所有权的步骤;当所有者1不再需要该对象时及时放弃了所有权,但此时所有者2依然拥有该对象,因此该对象依然存在,所有者2可以继续使用它;当所有者2也不再需要该对象时,也放弃掉所有权,这时对象以不再有任何所有者(相应的引用计数也变为0),因此立刻被销毁掉。 需要注意的是,所有者2只是复制了该对象的指针,并没有使用copy方法,因此复制指针这个操作本身并不增加对象的引用计数;而正因为所有者2希望能使用该对象,因此通过retain方法成为它的所有者,也保证了所有者1放弃该对象时,对象不被销毁。


iPhone cocos2d是一个用于创建2d游戏、交互应用的框架。早已听说过这个著名的框架,但懒惰的我并没有去尝试一下,直到最近一起做iPhone开发的好友跟我大力推荐,并以他们自己用cocos2d做出来的绚丽游戏向我现身说法,我才明白错过了多么好的一个东西。今天初体验了一番,发现其封装的确实很适合游戏编写。简单show一下几个截图,研究更深以后再做详细介绍。 箱子坠落和碰撞。 小人摇头晃脑。 安装: 1. 在 http://code.google.com/p/cocos2d-iphone/ 下载cocos2d包,并解压缩。我下载的版本是0.8.2。 2. 打开终端。输入cd;将文件夹拖入终端,回车。 3. 这时将install_template.sh拖入终端,回车。然后安装模板的过程就开始了,终端上会出现一堆文字,最后显示done。 4. 打开XCode,New Project下应当出现了三个cocos2d模板

  评论这张
 
阅读(1503)| 评论(0)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018