2 番目のメソッドで追加のポインターを作成することを除いて、結果に違いはありません。どちらのバージョンでself.cclass
も、オブジェクトを問題なく保持できます。
問題は、2 番目のモードでのみオブジェクトを解放すると、最初のモードでメモリ リークが発生することです。retainCount
オブジェクトを割り当てると +1 になるため、setter を介して +1 オブジェクトを割り当てます。これは、実際にretainCount
もう一度ぶつかることを意味します。オブジェクトをプロパティに割り当てた後にオブジェクトを解放しない場合、そこから解放されると、は 1 だけ減少します。したがって、 +1retainCount
のオブジェクトがメモリ内を浮遊し、永久に失われます。retainCount
しかし、あなたはすでにより良いバージョンについて尋ねているので、遅延インスタンス化を紹介したいと思います。できることは、問題のプロパティの getter メソッドを上書きし、まだ割り当てられているかどうかを確認することです。そうでない場合は、getter メソッド内で割り当ててから返します。次のようになります。
- (CustomeClass*) cclass
{
if(!_cclass)
{
_cclass = [[CustomeClass alloc] init];
}
return _cclass;
}
このメソッドでは、+1 保持オブジェクトを内部変数に割り当てます。したがって、setter をバイパスし、retainCount
. また、オブジェクトは本当に必要な場合にのみインスタンス化されるため、メモリに優しいです。プロパティを nil または新しいオブジェクトに設定すると、古いオブジェクトは適切に割り当て解除されます。
編集:
Robert Ryan のコメントに応えて、以下を追加します。
これにより KVO が壊れたり、プロパティに割り当てられた資格が妨げられたりすることはありません。プロパティがassign
またはとしてマークされている場合weak
、遅延インスタンス化はあまり意味がありません。としてマークされている場合、retain
またはstrong
オブジェクトをインスタンス化するこの方法は完全に問題ありません。特に、構成メソッド内でとにかく割り当てるプロパティである場合はそうです。
KVO について: getter 内で割り当てられた値は初期値/デフォルト値と見なすことができるため、KVO は引き続き機能します。セッターを使用してプロパティに何か他のものを割り当てると、トリガーされます。デフォルト値が原因で KVO がトリガーされるのは望ましくありません。