请教各位iOS Dever我是一名iOS开发入门新手,近日来一直在读《Objective-C基础教程》[美]Mark Dalrymple & Scott Knaster著
在看到P133页9.1.3节“访问方法中的保留和释放”遇到一个搞不明白的地方:原文摘抄如下:
---------------------------------------------------------------------------------------------------------
下面是编写setEngine:方法的另一种方法:- (void) setEngine: (Engine *) newEngine
{
[engine release];
engine = [newEngine retain]; // More BAD CODE: do not steal. Fixed version below.
} // setEngine该例子修复了前一个例子中engine1对象泄漏的错误,但是当newEngine对象和原来的
engine对象是同一个对象时。这段代码也会出问题。考虑下面的情况:Engine *engine = [Engine 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]返回一个指向
engine对象的指针,该对象的保留计数器值为1。setEngine方法的第一行是[engine release],
该语句将engine对象的保留计数器值归0,并释放engine对象。现在,newEngine和engine
这两个实例变量都指向刚释放的内存区,这会引起错误。……
---------------------------------------------------------------------------------------------------------我不明白的是代码最后一行[car2 setEngine: [car1 engine]];怎么会发生后面文字的解释呢?
我自己的计算结果是最后一行执行完时count还是2。我是这么理解的:
第一行发送new消息创建了一个新的engine对象,这时engine对象的count值为1
第二行和第三行分别创建一个car1和car2对象
第四行给car1对象发送setEngine消息,在方法体内首先car1原有的engine实例变量release,
然后令作为参数的newEngine的保留计数器加1并赋值给car1的engine实例变量。(这时car1
的engine实例变量也指向engine对象,且count值为2
第五行像engine对象发送release消息,使其count值为1
最后一行给car2对象发送setEngine消息,在方法体内首先car2原有的engine实例变量release——就是这里没搞懂!这个是car2自己原有的engine实例变量,暂时和前面的engine对象以及作为参数传入的car1的engine实例变量还没有发生关系!——至少我是按照这个思路理解的。然后令作为参数的car1的engine实例变量的保留计数器加1并赋值给car2的engine实例变量。(这是car1的engine、car2的engine都指向engine对象,且count的值为2。——与代码后面的描述不一致。是不是我理解方式不对路啊?还是说是书中的例子写的有问题?

解决方案 »

  1.   

    最烦看书,你直接查下 retain--是干嘛用得不就行了retain 我理解 autorelease得对象 你要用就得先把他retain下。
      

  2.   

    没看过这本书,不过从的描述上看,书中的例子我觉得不对。
    - (void) setEngine: (Engine *) newEngine
    {
    [engine release];
    engine = [newEngine retain];
    }
    这样的写法不能避免的是这种情况:
    Engine *engine = [Engine new];
    Car *car1 = [Car new];
    [car1 setEngine: engine];
    [engine release];
    [car1 setEngine: [car1 engine]];
    //在这之后无论使用engine还是使用[car1 engine]都会抛出异常。应该是这样吧。
      

  3.   

    最新版的XCode中Object-c有变化,已经自己处理retain和release了,开发者可以不管这些了
      

  4.   

    我在看到这里的时候也发现了这个疑问,然后google到了你这篇文章当然还有其他的,说起来楼主本身的见解就是正确的,2楼的也是正解。这个例子本身跟后面的解释是对不起来的。
      

  5.   

    那么定义这个car2是干啥?
    专门迷惑我们看书的?
      

  6.   


    那么定义这个car2是干啥?
    专门迷惑我们看书的?