这段代码中的保留计数是多少?

时间:2013-11-13 06:29:23

标签: objective-c automatic-ref-counting

从“学习Objective-C on the mac(第二版)”一书中。 为什么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;
}

2 个答案:

答案 0 :(得分:2)

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

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

some_function内:

  1. engine,本地变量
  2. car1.engine
  3. car2.engine
  4. setEngine:方法中:

    1. engine,ivar
    2. newEngine,参数
    3. 以下是代码中发生的事情:

      1. engine = [Engine new];保留引擎,保留count = 1
      2. [car1 setEngine:engine];
        • [engine release];释放汽车的引擎ivar,可能设置为nil,并且什么都不做。保留计数= 1
        • engine = [newEngine retain];保留引擎,保留count = 2
      3. [engine release];释放引擎,保留count = 1
      4. car2 setEngine:engine];
        • [engine release];释放汽车的引擎ivar,可能设置为nil,并且什么都不做。保留计数= 1
        • engine = [newEngine retain];保留引擎,保留count = 2
      5. 现在,请帮个忙,让编译器为您处理引用计数。

答案 1 :(得分: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;
}