"Learn Objective-C on the Mac"书上的勘误表或记忆理解不良?



在《在Mac上学习Objective-C》一书中,你可以找到以下代码,我认为这是一个勘误表:


"这是另一个尝试写setEngine:

- (void) setEngine: (Engine *) newEngine  
{  
      [engine release];  
      engine = [newEngine retain];  
}

…思考这个例子:

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]]; //Ops...

为什么这是一个问题?事情是这样的。[car engine]返回一个指向引擎的指针,该指针的保留计数为1。setenengine的第一行是[engine release],它使retain计数为0,对象被释放...."


然而,在阅读了第166页的这段话之后。我想知道car2的内部引擎参考与car1的引擎有什么关系。它们是两个不同的引用,当调用"[car2 setenengine: [car1 engine]]"时,car2中的引擎尚未初始化,并且与作者所说的保留的引擎没有任何关系。所以"[引擎释放]"不会将car1引擎的计数器降为0。明白我的意思了吗?这是勘误表还是我大错特错了?

((我想讨论这个特定的代码,而不是实现setter的正确方法))

setenengine:在什么类中?我猜是在车里。这个Car有一个Engine*类型的实例变量Engine。这是不相同的引擎*指针在第二个代码片段(这应该是一个控制器类与它自己的实例变量)。

首先,初始化引擎。[Engine new][[Engine alloc] init]相同(对于所有实际目的)。

你有两个Car对象和一个Engine对象。将car1中的引擎实例变量设置为指向引擎对象。然后释放原始指针。很好。然后把它也分配给car2。如果car2有一个不同的引擎,它就会被释放,并被分配新的引擎。如果它没有分配引擎,则释放消息被发送到nil(这很好),并且它也被分配。

一切都好。

PS -虽然Objective-C有new结构,但使用它通常是一个坏主意,因为它模糊了两阶段创建模式,这是苹果框架的标准。使用alloc &init .

设置不正确。可能是:

- (void) setEngine: (Engine *) newEngine  
{
  if(newEngine != engine)
  {
   [engine release];  
   engine = [newEngine retain]; 
  }
}

最新更新