内存管理

 

      这里浅谈一下objective c 的内存管理模式。内存管理这一块我每看一次都觉得有收获,以前都是自动垃圾回收的,不习惯objective c 尤其是在iphone os平台上的处理方式。

      其实objc本身也有一个自动处理程式,即所谓的自动释放池(NSAutoteleasePool),它可以自动释放添加到该池中的对象使用的内存:程序最后加一句消息drain 给pool ,可以在释放池的时候将添加到该池的所有对象一同释放。对于mac os平台,我们完全不用管内存的问题,而不用担心内存不够。但是仅靠pool自动释放势必会造成大量的内存浪费。举个通俗的例子。我们在程序的开始新建了一个对象,并将该对象丢进自动释放池,那么该对象将一直存在,直到我们在程序尾发送drain消息给pool,也就是说他将无条件占用我们宝贵的内存。如果该对象只是我们用来作中介用的,使用一次后便不再有用,那之后它的存在毫无意义!可是我们能把它怎样呢,我们不可能在程序中途释放pool,因为那将同时释放其它有用的对象!

      于是我们会自然想到,提供一种方法,可以随时释放特定的内存!这样不就完美了吗?事实上objc确实提供了一种方法:release。如代码[aFraction release]就是释放对象aFraction.

      但是问题不是这么简单。在程序中一个对象可能被我们多次引用,它可能存在于一个数组中,也可能被其它位置的实例变量引用,如果你认为当前的某个对象aFraction对我已经没有利用价值了,将其处理掉,问题出现了,其它可能引用该对象的变量将同时瞬间化为乌有!这就麻烦了!我们不可能花费大量精力去记住这个对象在什么地方被引用了吧!但是不知道它是否被引用,我们又不能放心的释放它。

      foundation框架为我们提供了一种解决方案:引用计数。系统为我们记下某个对象的引用次数,每当我们引用一次对象时,发送消息retain给该对象,则计数加1。当该引用无用了时,发送消息release给该对象,计数减1。注意,只是计数减1,而不是释放该对象!只用当计数被减到0时,系统自动释放该对象。这就解决了我们前面提到的问题。

      对于iphone这样仅有16G内存的平台,可想而知节省内存是多么重要!因此我们应该习惯这样的内存管理方式,只要引用了某个对象,每当觉得不再有用的时候,就该及时发送release给它,而不是依赖[pool drain]来统一处理(事实上iphone不支持NSAutoreleasePool吧?)。

      这里又牵涉到内存分配的问题了。什么时候才叫真正的对象引用呢?我们知道一个指针可能在多处被使用,但并不是每一次使用都是为它重新分配了内存的,有些时候只是简单的调用而已。如果我们不清楚这点,就很可能因此造成错误。试想我们“引用”了一下对象aFraction,但并没为其分配地址,当我们不再使用该引用时,如果release,就很可能将该对象误释放!有些抽象哈,举个简单的例子。

      比如有个string 型对象message,要对其赋值可以有多种方式:

      一、message=aMessage; 

      二、message=[aMessage  copy];

      三、message=[aMessage  retain];

      四、message=[NSString  stringWithString:aMessage];

      ……

         还有什么alloc init之类等等……

         我们就要注意其本质的内存分配了,书面语既是要注意是浅复制还 是深复制。第一种方法所获得的message,其实并没有它自己的内存,如果我们释放aMessage,  message 会在不经意间消失;释放message,  aMessage也会受影响……

         总之在objc中,我们要特别警惕某些对象是否指向同一地址,什么时候需要我们来release/delloc,哪些东西放在了NSAutoreleasePool里了,以什么方式建立的对象需要我们来释放内存,什么时候释放……对于这些东西实在应该归纳下

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值