0

摘自《在 Mac 上学习 Objective-C(第二版)》一书。为什么retain count在以下代码块中是 2 而不是 1:-

- (void) setEngine: (Engine *) newEngine
{
   [engine release];
   engine = [newEngine retain];
   // More BAD CODE: do not steal. Fixed version below.
}  // setEngine

some_function 
{
   Engine *engine = [Engine new]; // count: 1

   Car *car1 = [Car new];
   Car *car2 = [Car new];

   [car1 setEngine: engine];   // count: 2 But why? 1-1=0 (due to [engine release]  
                              // in -(void) SetEngine.    
                              // and after engine=[newEngine retain] retain count is 1.

   [engine release]; // count 1 
   [car2 setEngine: [car1 engine]]; // oops!

   return 0;
}
4

2 回答 2

2

首先,请考虑切换到ARC。在普通编程中确实没有理由需要使用 MRC。

其次,你把你的范围弄混了。请记住,这段代码中确实有五个Engine*指针,但只有一个Engine对象。

some_function

  1. engine, 局部变量
  2. car1.engine
  3. car2.engine

setEngine:方法内:

  1. engine, 伊瓦尔
  2. newEngine, 参数

这是代码中发生的事情:

  1. engine = [Engine new];保留引擎,保留计数 = 1
  2. [car1 setEngine:engine];
    • [engine release];释放汽车的引擎 ivar,它可能设置为nil,并且什么都不做。保留计数 = 1
    • engine = [newEngine retain];保留引擎,保留计数 = 2
  3. [engine release];释放引擎,保留计数 = 1
  4. car2 setEngine:engine];
    • [engine release];释放汽车的引擎 ivar,它可能设置为nil,并且什么都不做。保留计数 = 1
    • engine = [newEngine retain];保留引擎,保留计数 = 2

现在,请帮自己一个忙,让编译器为您处理引用计数。

于 2013-11-13T06:46:49.787 回答
0

请检查我的评论

- (void) setEngine: (Engine *) newEngine
{
   // setEngine: is method defined inside Car.
   // so engine reference is retained by Car
   // and it should be released when Car is released 
   // ie. in car dealloc method
   [engine release];
   engine = [newEngine retain];
   // More BAD CODE: do not steal. Fixed version below.
}  // setEngine

- (void)dealloc{
  [engine release]; // Retaining count is reducing
  [super dealloc];
}    


some_function 
{
   Engine *engine = [Engine new]; // count: 1

   Car *car1 = [Car new]; // +1 for car1
   Car *car2 = [Car new]; // +1 for car2

   [car1 setEngine: engine];   // count: 2 But why? 1-1=0 (due to [engine release]  
                              // in -(void) SetEngine.    
                              // and after engine=[newEngine retain] retain count is 1.

   [engine release]; // count 1 
   [car2 setEngine: [car1 engine]]; // count 2 - Here Car2 retaining same 
                                    //engine retained by Car1. So retain 
                                    //count of engine increases.

   [car1 release];// count 1
   [car2 release];// count 0


   return 0;
} 
于 2013-11-13T06:53:55.807 回答