10

たとえば、viewDidLoadメソッドのどこにあるかという代わりに、サンプルコードが常に表示されます。

someInstanceVar = [[Classname alloc] init];

彼らはいつも行きます

Classname *tempVar = [[Classname alloc] init];
someInstanceVar = tempVar;
[tempVar release];

どうしてこれなの?まったく同じことではありませんか?

4

1 に答える 1

12

簡単な答え:このパターンは、すべてのメモリ管理ルールを尊重し、適切な副作用を呼び出しながら、新しいオブジェクトを作成してメンバー変数に割り当てるための最良の方法と考えられているため、iPhoneコードに常に表示されます(いずれか)自動リリースの使用も避けながら。

詳細:

2番目の例ではvar、解放されたメモリへのポインタを保持したままになっているため、ゾンビが作成されます。より可能性の高い使用例は次のようになります。

tempVar = [[Classname alloc] init];
self.propertyVar = tempVar;
[tempVar release];

それがまたはプロパティpropertyVarとして宣言されていると仮定すると、このコードは新しいオブジェクトの所有権をクラスに渡します。copyretain

アップデート1:次のコードは同等ですが、iOSでは推奨されません*。これが、ほとんどのiPhoneプログラムが代わりに最初のパターンを使用する理由です。

self.propertyVar = [[[Classname alloc] init] autorelease];

*自動リリースは、使いすぎると問題が発生する可能性があるため、iOSではお勧めしません。使いすぎないようにする最も簡単な方法は、すべてを使用しないことです。そのため、許容できる場合でも、alloc/initとを使用するiOSコードが頻繁に表示されます。これはコーダーの好みの問題です。releaseautorelease

更新2:このパターンは、Cocoaが舞台裏で自動的に実行するメモリ管理のため、最初は混乱しているように見えます。そのすべての鍵は、メンバー変数を設定するために使用されるドット表記です。説明のために、次の2行のコードが同一であると考えてください。

self.propertyVar = value;
[self setPropertyVar:value];

ドット表記を使用すると、Cocoaは指定されたメンバー変数のプロパティアクセサーを呼び出します。そのプロパティがcopyorretainプロパティとして定義されている場合(そして、ゾンビを作成せずにこのパターンが機能する唯一の方法です)、いくつかの非常に重要なことが起こります。

  1. 以前に保存された値はすべてpropertyVar解放されます
  2. 新しい値は保持またはコピーされます
  3. 副作用(KVC / KVO通知など)は自動的に処理されます
于 2010-09-27T18:37:18.877 に答える