2011-01-18 8 views
0

私はCocoaのメモリ管理の概念を理解しようとしています。 私は、次の部分:::で立ち往生していますココアでのメモリ管理

//This is wrong code. But i want to understand why it is wrong! 
- (void) setEngine: (Engine *) newEngine 
{ 
     [engine release]; 
     engine = [newEngine retain]; 
} 

ときnewEngineとエンジンものと同じ、そしてどのようにココアは、インスタンス変数として扱わすべき1パラメータとして1を決定していますか?例えば

Engine *engine = [Engine new]; // count: 1 
Car *car1 = [Car new]; 
Car *car2 = [Car new]; 

[car1 setEngine: engine]; // count: 2 -----How is the retain count 2 here? 
[engine release]; // count 1 

[car2 setEngine: [car1 engine]]; 

私は私のプログラムで効率を維持するように徹底的にこの概念を学びたいよう助けてください。私は多くの人が私と私の友人としてこのままで立ち往生していると確信しています..事前に感謝... :)

+0

あなたはコードをフォーマットする "{}" のアイコンを使用することができます。また、フレームワーク名はCOCOAではなく "Cocoa"です(略語ではありません)。 –

+0

よろしくお願いします: –

答えて

3

まず、あなたのセッターがオブジェクトが異なるかどうかを確認していることを確認します。

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

は、ここでは、このメソッドの内部で何が起こるかです:

  1. チェックに合格されたエンジンは、我々がすでに持っているものと異なっていることを確認します。それが同じであれば、何もする必要はありません。
  2. 古いエンジンをリリースします。私たちがそれを所有する最後のオブジェクトだった場合、その保持カウントはゼロになり、割り当て解除されます。古いエンジンがnilの場合、releaseメッセージは単に無視されます。
  3. エンジンを保持する新しいエンジン。それが他のどこかで公開されていれば、私たちはそれを所有しているため、割り当て解除されません。新しいエンジンがnilの場合、retainメッセージは単に無視されます。
  4. インスタンス変数をnewEngineに設定します。

、それが作成された1としてスタートしましたので、第二に、あなたはsetEngine:を呼び出した後、保持カウントが2であることを理由があります。次に、それを保持しているcar1にそれを割り当て、保持カウントを2にします。外部コードが car1を所有しているので、保持カウントは2です。 car1とcar2に同じ方法([car2 setEngine:car])で渡す必要があります。これにより、保持数は3になります。car1とcar2に渡したら、外部コードを解放することができます。これはObcjective-Cにあなたの外のコードはもはやそれを所有していません、所有権はcar1とcar2だけにあります。

ここでは完全な例です:

// create an engine, we will own it for now 
Engine *engine = [[Engine alloc] init]; 

/* engine retain count: 1, owned by this context */ 

Car *car1 = [[Car alloc] init]; 
Car *car2 = [[Car alloc] init]; 

// pass engine along to cars 
[car1 setEngine: engine]; 
[car2 setEngine: engine]; 

/* engine retain count: 3, owned by car1, car2 and this context */ 

// release engine, we no longer need it 
[engine release]; 

/* engine retain count: 2, owned by car1 and car2 */ 
+0

答えはThnx Simon ...私はこれまで説明したとおりに理解しました...しかし、setEngineの実行方法についてはまだ分かりません。同じ例のように - (void)setEngine:(Engine *)newEngine { [エンジンリリース]; //最初のエンジンがリリースされました。インスタンス変数またはメソッドの外部で作成されたオブジェクト? engine = [newEngine retain]; } –

+0

私は 'setEngine:'内部で何が起こっているのかの説明を追加しました。 –

+0

...と私はもう一度編集したので少しきれいです。 –