`
CreazyApple
  • 浏览: 64244 次
  • 性别: Icon_minigender_1
  • 来自: 成都
文章分类
社区版块
存档分类
最新评论

内存管理

阅读更多

 

这里浅谈一下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里了,以什么方式建立的对象需要我们来释放内存,什么时候释放……对于这些东西实在应该归纳下

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics