質問

オブジェクトを割り当てて初期化する次の2つの方法の違いは何ですか?

AController *tempAController = [[AController alloc] init];
self.aController = tempAController;
[tempAController release];

and

self.aController= [[AController alloc] init];

リンゴの例のほとんどは、最初の方法を使用しています。なぜ割り当て、初期化、オブジェクトし、すぐに解放するのですか?

役に立ちましたか?

解決

すべてのオブジェクトには参照カウントがあります。 0になると、オブジェクトの割り当てが解除されます。

プロパティが @property(retain)として宣言されていると仮定

最初の例、行ごと:

  1. オブジェクトは alloc によって作成され、参照カウントは1です。
  2. オブジェクトは self setAController:メソッドに渡され、 retain メッセージが送信されます(メソッドはオブジェクトがどこから来たかを知る)、参照カウントを2に増やします。
  3. 呼び出し元のコードはオブジェクト自体を必要としないため、 release を呼び出し、参照カウントを1に減らします。

2番目の例では、基本的にステップ1と2を実行しますが、3は実行しません。したがって、オブジェクトの参照カウントは2です。

ルールは、オブジェクトを作成した場合、それを使い終わったらリリースする責任があります。この例では、プロパティを設定した後、tempAControllerでコードが実行されます。そのオブジェクトを保持する必要がある場合、 retain を呼び出すのはセッターメソッドの責任です。

Objective-Cの self.property = foo; は、実際には [self setProperty:foo]; の略記であり、 setProperty:メソッドは、必要に応じてオブジェクトを保持またはコピーします。

プロパティが @property(copy)と宣言されている場合、オブジェクトは保持される代わりにコピーされます。最初の例では、元のオブジェクトはすぐに解放されます。 2番目の例では、元のオブジェクトの参照カウントは0であっても1になります。したがって、同じ方法でコードを記述したいと思うでしょう。

プロパティが @property(assign)と宣言されている場合、 self はオブジェクトの所有権を主張しておらず、他の誰かがそれを保持する必要があります。この場合、最初の例は正しくありません。これらの種類のプロパティはまれであり、通常はオブジェクトデリゲートにのみ使用されます。

他のヒント

他の人が指摘したように、表示する2つのコードスニペットは同等ではありません(メモリ管理の理由から)。 前者が後者よりも選ばれる理由について:

後者の正しい定式化は次のようになります

self.aController= [[[AController alloc] init] autorelease];

前者と比較して、これは自動解放プールの使用により追加のオーバーヘッドを追加し、状況によってはオブジェクトの寿命が不必要に延長され(自動解放プールが解放されるまで)、アプリケーションのメモリフットプリントが増加します。

他の「可能」な実装(例の出所による)は単純です:

aController = [[AController alloc] init];

ただし、インスタンス変数を直接設定することは、initメソッドまたはdeallocメソッド以外の場所では強く推奨されません。その他の場所では、常にアクセサメソッドを使用する必要があります。

これにより、サンプルコードに示されている実装が行われます。

AController *tempAController = [[AController alloc] init];
self.aController = tempAController;
[tempAController release];

次の理由から、これはベストプラクティスに従います。

  • 自動リリースを回避します。
  • メモリ管理のセマンティクスをすぐに明確にします;
  • アクセサメソッドを使用してインスタンス変数を設定します。

また、コードを1行に減らしたいという要望があるため、多くの人がAutoreleaseを使用していることに注意してください:

self.aController = [[[AController alloc] init] autorelease];

理論的には、iPhoneの自動リリースの方が多少高価です(その理由について明確な説明を聞いたことはありません)。

Xcodeを使用している場合、静的アナライザーでそのようなコードを検出するのに役立ちます。 [ビルド]をクリックします>>ビルドと分析

alt text

これにより、このようなコードで非常に役立つメッセージが表示されます。

alt text

注意すべきもう1つの点は、例がaControllerの@property定義にも依存していることです。

@property(readwrite、retain)id aController; として定義されている場合、サンプルは機能しますが、 @property(readwrite、assign)id aController; その後、releaseを余分に呼び出すと、オブジェクトの割り当てが解除されます。

することもできます

@property (nonatomic, retain)AController *aController;
...
self.aController= [[AController alloc] init];
[aController release];

保持プロパティを使用すると、同じように機能しますが、混乱を少なくするために(プロパティを保持するために)別の方法を使用する方が適切です。 、実際にはsetAControllerが保持するためにそうではない場合。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top