请教各位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。——与代码后面的描述不一致。是不是我理解方式不对路啊?还是说是书中的例子写的有问题?
在看到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。——与代码后面的描述不一致。是不是我理解方式不对路啊?还是说是书中的例子写的有问题?
- (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]都会抛出异常。应该是这样吧。
专门迷惑我们看书的?
那么定义这个car2是干啥?
专门迷惑我们看书的?