浅谈Objective—C内存管理技术及应用
2014-10-21任艳
摘 要:合理地内存管理机制能确保有效地管理内存资源。在Objective-C程序中,必须确保所创建的对象在不再需要它们的时候被销毁。Cocoa定义了内存管理规则和原则使得正确管理应用程序的内存变得容易和可靠。
关键词:Objective-C;内存管理;应用
中图分类号:TP311.11
在编写程序的过程中,有效和高效地管理内存资源是程序开发人员需要着重考虑的事情,一方面是为了保证应用程序的内存消耗尽可能低,另一方面是为了防止内存泄漏。为此,Cocoa定义了一些有助于内存管理的规则和原则。内存管理所要做的就是清理不用的内存,以便内存能够再次利用,即以某些方式确定一个对象不再需要使用了,并且它占用的内存能够被回收。
1 Objective-C内存管理规则
Cocoa提供了一种被称为“引用计数”或“保留计数”的机制,内存管理被放在对象创建与销毁的生命周期中,该机制不同于C语言中有方法(malloc/free)直接操作内存,也不同于GC语言自动管理内存。实际上,这种内存管理方式使得每一个对象都有一个引用计数,当对象被创建的时候,其引用计数为1;当引用计数减少到0时,对象会被销毁。
在Objective-C中,所有对象都被定义为指针;指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址,如果使用不当,就会出错或者造成内存的泄露。因此,在进行内存管理时,需要了解内存管理规则。Objective-C内存管理规则的主要内容:(1)把对象视为内存,只能释放或自动释放所拥有的对象。(2)当使用含有alloc、new、copy的方法创建对象,便拥有该对象的所有权;或者向对象发送retain消息,也会拥有该对象的所有权。(3)当不再使用对象时,向对象发送release或autorelease消息,将会释放对象的所有权。通常,在不适合立即回收对象的情况下才使用autorelease。(4)通过实现dealloc方法来释放所拥有的实例变量。(5)自由释放池(@autoreleasepool),即自动引用计数(ARC机制),这是一种半自动机制,可以手动设置或取消。自动内存释放使用@autoreleasepool关键字声明一个代码块,当代码块执行完之后,对象都会自动调用一次release方法,同时对象的销毁过程也得到了延迟(统一调用release方法)。
2 常见错误及对策
内存泄露主要是指由于设计的失误对某块内存失去控制,而这块内存不能被再次使用,导致了内存的浪费。当发生内存泄露或别的内存问题时会比较麻烦,因为编译器不会自动发现这类错误,通常是在程序运行时才能捕捉到;同时,Objective-C 2.0后引入的ARC机制,也不能完全避免内存泄露等问题。避免内存问题、解决内存泄露的办法:(1)为了防止内存泄露,当使用alloc或copy创建了对象,或者使用retain保留了对象,我们都必须通过release方法释放。(2)改写dealloc方法,在需要的时候释放内存。(3)手动创建autoreleasepool,该方法使得无须等待系统释放所创建的对象,便可告诉系统在代码段结束时释放对象。(4)大多数情况下,申请内存的语句数量和释放内存的语句数量应该相等。
3 应用实例
以下是内存管理的一个例子,首先定义了一个类Student,包含两个实例变量name和age,自定义相应的setter和getter方法,并手动管理内存,该例子给出了一个内存泄露的情况,并在最后给出解决方案。
3.1 Student类的接口文件的定义:
3.2 Student类的实现文件的定义:
3.3 主方法main的实现如下:
从运行结果发现,当对象stu的实例变量name被字符串s2=”Jacky”重新赋值,此时,原来定义的字符串s1不再使用,但是它的引用计数仍然为1,到最后它所占用的内存都没有被释放。
导致这种问题的产生的根源在-(void)setName:方法上,当[stu setName:s1]时,name拥有了s1的使用权;接下来,当用户使用[stu setName:s2]来替换了原来s1的值时,并没有对name发送release消息,那么name对于s1的使用权就没有释放,但此时name的值已被s2所取代,即此刻name拥有了s2的使用权,而s1不再使用,而此时s1的引用计数仍为1,所占用内存没有正常回收,故产生了内存泄露。
为了解决该内存问题,我们在原来的-(void)setName:方法中,增加[name release];这行代码(即原方法中被注释掉的一行),该代码使得原来name没有正确释放它所拥有的对象的使用权的问题得到解决,相应的内存管理过程也正确了。同时,需要说明的是,当初次执行[name release];时,name的值为nil,而在Objective-C程序中,向nil发送任何消息都不会报错。
4 结束语
综上,只要掌握了Objective-C中的内存管理的正确方法和步骤,很多不必要的内存问题和内存泄露是完全可以避免的。
参考文献:
[1]杨正洪,郑齐心,李建国.Objective-C程序设计[M].北京:清华大学出版社,2011.
[2]Stephen G.Kochan著,林冀,范俊,朱奕欣译.Objective-C程序设计(第4版)[M].北京:电子工业出版社,2012.
[3]Scott Knaster,Waqar Malik,Mark Dalrymple著,周慶成(译).Objective-C基础教程(第2版)[M].北京:人民邮电出版社,2013.
作者简介:任艳(1982.04-),女,教师,讲师,硕士研究生,研究方向:现代数据库技术。
作者单位:苏州高博软件技术职业学院,江苏苏州 215100