下部の更新。
合成されたプロパティを操作(保持)する場合、deallocの役割を実行する最良の方法は、プロパティをnilに設定することです。これが「最良の」方法であると私が言う理由は、それが財産宣言によって暗示されるすべての契約が確実に満たされるようにするためです。たとえば、プロパティがアトミックであると宣言された場合(特に非アトミックであると宣言しない限り)、deallocでのこのプロパティの設定解除が同じアトミック保証で行われることを保証する唯一の方法は、 Deallocのプロパティ。また、オブジェクトのKey-Valueオブザベーションに関して正しく動作することも意味します。これは、Cocoaバインディングを使用する場合に特に重要になる可能性があります。
対応するプロパティのない(おそらくプライベートな)インスタンス変数に対して独自のメモリ管理を行う場合、いくつかのイディオムがあります。最も単純ですが、最も危険なのは、次のようにiVarをリリースすることです。
- (void)dealloc
{
[myArray release];
[super dealloc];
}
これにより、iVarの保持が解放されますが、他の人が述べたように、現在は古くなっている可能性のあるポインターが、誤って存在する可能性のあるオブジェクトを指している可能性のある古くなったポインターまたは保持されていないポインターによってアクセスされる可能性があります。割り当て解除。次は、別の回答で提案されているイディオムです。
- (void)dealloc
{
[myArray release], myArray = nil;
[super dealloc];
}
このためのさらに安全な、より衒学的なイディオムは次のとおりです。
- (void)dealloc
{
id temp = myArray;
myArray = nil;
[temp release];
[super dealloc];
}
これにより、ポイントされたオブジェクトを解放する前にiVarをクリアすることにより、ポインターの読み取りが古くなる可能性がさらに制限されます。ただし、命令の並べ替えの可能性があるため、これでもすべてのアーキテクチャでの古い読み取りに対する100%の保証ではありません。
並行性とメモリ管理のトピックについてはまだまだ多くのことが言えますが、一般に、@ synthesizedプロパティセッターがある場合は、それをdeallocで使用する必要があります。そうすることは、@ propertyの動作を変更した場合、deallocの動作が@property宣言に関して自動的に正しくなることを意味します。
重要な注意:アトミックプロパティの使用!=スレッドセーフ。(実際、私に尋ねると、原子特性は無駄ですが...)詳細については、ここを参照してください。
アップデート
これは最近再び賛成され、合成された保持プロパティを使用したアトミック保証についてここで述べたことを支持し、元の回答の他のコンテンツはそれ自体で価値がありますが、反対側に伝える必要があると感じています物語。Dave DeLongはコメントでこれのいくつかをほのめかしました、しかし私はそれが主な答えに詳細を加える価値があるだろうと思いました。
アトミック性の保証を維持する唯一の方法はnil
、セッターを介してプロパティを設定することです。しかし、気にする必要はありません。理由は次のとおりです。オブジェクトがdealloc
編集されている場合、それは(オブジェクトグラフが正しい場合)そのオブジェクトへの生きた参照があってはならないことを意味します。オブジェクトへの生きた参照がない場合、プロパティをクリアする操作の原子性の保証を気にすることはできません。
セッターを使用する理由として、元の回答でKVOについても言及しましたが、dealloc
DaveDeLongはコメントで対位法としてKVOについて言及しました。彼は正しいです。その理由は次のとおりです。オブジェクトがdealloc
編集されている場合、すべてのKVOオブザーバーはすでにそのオブジェクトから削除されているはずです(ここでも、KVOであるかどうかに関係なく、生きている参照はありません)。実際、そうでない場合は、観測が行われたままオブジェクトが消えたことを通知するコンソールメッセージが表示されるまで長くはかかりません。
要するに、で合成されたセッターと同等の原子性の保証をすることはできませんがdealloc
、それは決して重要ではありません(もしそうなら、何か他のものが壊れています)。