ISO--内存管理

 

  在iPhone开发中,对内存进行正确的管理是非常重要的一个方面。iPhone有128MRAM,但其中约有一半的容量要用于屏幕缓冲和其他系统进程,同时iPhone不支持将内存写到交换文件,所以iPhone只有大约64M的内存用来运行应用程序,且严格受到物理内存量的限制。这样,基本上不容许我们开发的软件存在任何的内存泄露。

  iPhone中的内存管理

  由于iPhone对内存严格的要求,所以当一个对象不再需要时,要及时释放它所占用的内存空间。

  Objective-C 的内存管理采用了基于引用计数(Reference Count)这种非常常用的技术。简单讲,每个对象都有一个与之关联的整数,可以将它称为引用计数器或保留计数器,如果要使用一个对象,并确保在使用期间对象不被释放,需要通过函数调用来取得“所有权”,即引用计数器加1,使用结束后再调用函数释放“所有权”,使引用计数器减1。“所有权”的获得和释放,对应引用计数的增加和减少。引用计数为正数时代表对象还有引用,为0时代表可以释放。

  回想前面的例子,[NoteClass alloc]就是为对象分配内存并使它的引用计数器的值为1,而[note1 release]则是负责将note1对象的引用计数值减1,如果检测到note1的引用计数值为0,则note1对象会被释放掉,同时调用 dealloc方法。但在这里要牢记的是,在Objective-C中,必须严格使用引用计数机制来控制内存的分配与释放,当对象的引用计数为0时,对象会自动进行释放,并调用dealloc方法,我们绝不可以自行调用dealloc方法。

  下面就来详细说明一下内存是如何管理的。

  用于内存管理的方法

  在开发过程中,主要使用以下方法来对内存进行管理。

  获得对象当前引用计数的方法

  (1) -(NSUInteger)retainCount:方法返回当前对象的引用计数值。

  获得对象所有权的方法:

  (1) +(id)alloc:这是一个类方法,相信现在你已对它非常熟悉了,它负责为新建的对象分配内存并将新对象返回,同时将该对象的引用计数值设置为1。如果使用了该方法,则被创建的对象要负责调用release方法或autorelease方法来释放对象所有权,从而避免内存泄露。

  (2) ? (id)copy:拷贝引用该方法的对象,返回新复制的对象,被赋值的对象引用计数值加1。像obj1 = [obj2 copy],该语句表示复制对象obj2,并将复制结果赋给obj1,同时将obj1的引用计数值加1。
  (3) ? (id)retain:将调用该方法的对象的引用计数值加1。

  另外,名字中带有alloc, copy, retain 字样的函数,一般都会为引用计数值加1,这是一个在Cocoa中对方法的命名习惯。

  释放对象所有权的方法

  (1) ? (oneway void)release:负责将对象的引用计数值减1。如果对象的引用计数值减为0,则会调用该对象的dealloc方法,对该对象进行释放。

  (2) ? (id)autorelease:某些情况下,我们并不想取得对象所有权,又不希望对象被释放,例如在一个函数中生成了一个新对象并返回:

  - (NSString *)description {

  NSString *desc = [[NSString alloc] initWithString:@"iPhone!"];

  return (desc);

  }

  像其中的desc对象就是这种情况,description方法需要返回desc变量,所以不能释放它,但在方法之外又没有获取desc的所有权,无法释放。那么应该怎么办呢?

  还记得前面的NSAutoreleasePool * pool吗?该对象被称为自动释放池,如果某个对象obj在自动释放池创建NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]与销毁[pool drain]之间使用[obj autorelease],则该对象就会被放在自动释放池中,表示会被自动释放,当自动释放池被销毁时,将该对象引用计数值减1。所以,我们可以对上面的 desc对象做如下修改,将它放到自动释放池中:添加[desc autorelease]语句或将用于初始化的一句改为[[[NSString alloc] initWithString:@"iPhone!"] autorelease]。

  同时,对于没有使用上面讲的三个获得对象所有权方法的对象,将自动放在自动释放池中,如本章一开始的例子中的NSString *note1 = [NSString stringWithString:@"Running at 6 o’Clock"]中的note1对象。

  自动释放池的效率并不高,所以在iPhone开发时,并不建议使用。

  下面,来修改一下Note.m文件,这次所做的修改对于实际记录事情也许并没有多大意义,但它可以很好的帮助我们来理解内存的管理:(具体实例与解析请参看《iPhone应用程序开发指南(基础篇)》)。

  其他注意事项

  以上便是关于内存管理大体的方法,下面来看一些关于内存管理的细微之处与实际使用时的小技巧:

  (1) 各种容器类如NSArray, NSDictionary, NSSet 等,会将引入的元素的引用计数值加1来获得所有权,而在元素被移除或者整个容器对象被释放时,释放容器内元素的所有权。  (2) iPhone开发中不支持垃圾回收机制。

  (3) 对象最好在需要时再创建,从而节省内存开销。

  (4) 绝不可以发送release消息给autorelease对象。

  (5) 在需要频繁分配与释放内存的地方(如for循环) ,可以创建自己的NSAutoReleasePool。

  内存管理规则

  本节将来总结一下进行内存管理时的主要规则,在今后的开发中遵循这些规则,会使我们少出很多错误。

  (1) 获得所有权的函数要和释放所有权的函数一一对应。

  (2) 在对象的 dealloc函数中释放对象所拥有的变量并调用父类的dealloc方法。

  (3) 永远不要直接调用dealloc来释放对象,只使用引用计数来完成对象的释放。

  大道至简,我们应首先牢固掌握这三条,这样,在今后的开发过程中,程序在内存方面应该就会平安无事了。

转载于:https://www.cnblogs.com/appios/archive/2012/08/01/2618313.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值