当前位置: 代码迷 >> Iphone >> 新手提问,问个关于内存管理方面的有关问题
  详细解决方案

新手提问,问个关于内存管理方面的有关问题

热度:56   发布时间:2016-04-25 06:06:22.0
新手提问,问个关于内存管理方面的问题
本帖最后由 z550946941 于 2012-12-27 17:20:52 编辑
第一种情况:

-(void) setEngine:(Engine *) newEngine{
   engine = [newEngine retain];
}//Car类的一个setter方法

main方法中的操作代码:

Engine *engine1 = [Enging new];//count: 1
[car setEngine:engine1];//count: 2
[engine1 release];//count: 1

Engine *engine2 = [Enging new];//count: 1
[car setEngine:engine2];//count: 2


书中对这段有问题的代码是这样描述的:
engine1有问题,因为它的 retain count 仍然为1. 
main方法已经释放了对engine1的引用,但是 Car 没有. 
engine1被漏掉了,那么engine1这个对象将会一直存在并且占用一部分内存.

第二种情况:

-(void) setEngine:(Engine *) newEngine{
   [engine release];
   engine = [newEngine retain];
}//Car类的一个setter方法

这种写法解决了第一种情况中出现的问题,但是当遇到下面的情况时,又会出问题

Engine *engine = [Enging new];//count: 1
Car *car1 = [Car new];
Car *car2 = [Car new];

[car1 setEngine:engine];//count: 2
[engine release];//count: 1

[car2 setEngine:[car1 engine]];//oops


书中的原文对问题是这样描述的:
[car1 engine] 返回了一个retain count 为1 的 engine的指针. 
第一行的 setEngine已经执行了[engine release] 让 engine 变量的 
retain count 变成了 0, 并且这个engine对象已经被回收.那么现在 newEngine
和 engine 实例变量都指向了一段已经被释放的内存导致程序错误.

上面的几段代码想必看过《Learn Objective-C on the Mac》这本书的童鞋都看到过吧.
我所不理解的是,通过对objective-c的学习,当一个对象的retain count 值为0时表示这个对象已被回收,

我的问题1:
如果我在 setEngine: 方法里直接写:
engine = newEngine;
那第一种情况中所提到的问题应该就不会存在了吧?
我的问题2:
engine = newEngine;

engine = [newEngine retain];
有什么不同

还有一个问题就是:
如果项目使用了 ARC 之后关于内存管理这块就可以完全交给系统处理吗?

------解决方案--------------------
你的问题1:
如果你不对新来的值retain,那么你只是简单的引用它而没有拥有权,这是弱引用;这样会出现什么情况呢?就是当你的newEngine释放的时候,你的engine也就没了。那么就会出现EXC_BAD_ACCESS;

你的问题2:
@1  engine = newEngine; 弱引用

@2  engine = [newEngine retain]; 强引用

@1只是简单地指向newEngine,并没有newEngine的拥有权,当newEngine释放掉后,engine同时也被释放了
@2是强引用,当newEngine retain后,newEngine的引用计数+1,可以这么讲,newEngine有一根线连到了XX这块内存区域,而engine也有一根线连到了XX这块内存区域,当[newEngine release]之后,只是把newEngine到XX的线给断了,而engine这根没断,所以 engine可以继续使用。

你的还有一个问题的就是:
使用的ARC不是说就是内存管理交给了系统。在使用ARC的环境下,你必须明确的表示出当前这个变量的拥有权,要使用__autoreleasing
__strong
__unsafe_unretained
__weak
这些来表明当前对对象的拥有权。而且像Core Foundation这种库也不参与ARC,你还是必须使用CFRelease()等这些方法来释放你的CF Object。
综上所述,如果你使用ARC,但对对象的所有权仍表示的不清楚,依然会内存泄漏。
  相关解决方案