0

本「MacでObjective-Cを学ぶ(第2版)」より。retain count次のコードのチャンクで 1 ではなく 2 である理由:-

- (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 を使用する必要がある理由はまったくありません。

第二に、スコープが混同されています。このコードには実際には 5 つのEngine*ポインターがありますが、Engineオブジェクトは 1 つしかないことに注意してください。

以内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 に答える