オブジェクトの参照に値が割り当てられているかどうかを簡単に確認して、オブジェクトnilが解放されたことを示すことができますか?
いいえ、releaseオブジェクトへのメッセージの送信nilと変数への割り当ては、2つの異なる無関係なものであるためです。
最も近いのは、強い/保持またはコピーするプロパティに何かを割り当てると、アクセサメッセージに変換され、プロパティの以前の値が解放されることです(これはセッターによって行われます)。それでも、KVOを使用してプロパティの値を監視することは、オブジェクトがいつリリースされるかを知ることを意味するわけではありません。特に、所有オブジェクトの割り当てが解除された場合、所有オブジェクトreleaseに直接送信しても通知は届きません。また、コンソールに警告メッセージが表示され(所有しているオブジェクトが監視中に死亡したため)、単体テストからのノイズの多い警告メッセージは必要ありません。さらに、これを実行するには、すべてのオブジェクトのすべてのプロパティを具体的に監視する必要があります。1つを見逃すと、バグを見逃す可能性があります。
オブジェクトへのreleaseメッセージは、そのオブジェクトを指す変数には影響しません。割り当て解除も行いません。
これはARCでわずかに変更されます。参照さnilれるオブジェクトがなくなると、弱い参照変数が自動的に割り当てられます。ただし、定義上、変数を強く参照することはあまり役に立ちません。オブジェクトへの強い参照がある場合、強い参照があるため、オブジェクトは消えません(まあ、そうすべきではありません)。それを生かしておく(すべき)でしょう。オブジェクトが死ぬ前に死ぬことは、あなたが探している問題の1つであり、ツールとして使用したいものではありません。
理論的には、作成するすべてのオブジェクトへの弱参照を作成できますが、コード内で手動でその変数を作成して、すべてのオブジェクトを具体的に参照する必要があります。ご想像のとおり、ものすごい苦痛と間違いなく物を見逃します。
また、オブジェクトが実際にリリースされるタイミングについて、どのような保証がありますか?
オブジェクトはメッセージを送信することで解放されるreleaseため、オブジェクトはそのメッセージを受信すると解放されます。
おそらくあなたは「割り当て解除」を意味しました。リリースすると、そのポイントに近づくだけです。オブジェクトは何度もリリースされる可能性がありますが、各リリースが以前の保持と単にバランスをとっていれば、オブジェクトの前に長い寿命があります。
オブジェクトは、最後に解放されたときに割り当てが解除されます。これはすぐに起こります。悪名高いretainCount人は、書き込もうとした多くの賢い人while ([obj retainCount] > 0) [obj release];が知っているように、0まで下がることさえありません。
実際には2つの答えがあります。1つは自動解放プールを使用し、もう1つは使用しません。
自動解放プールを使用するソリューションは、自動解放されたオブジェクトに対してのみ機能します。定義上、自動解放されないオブジェクトはプールに入りません。特定のオブジェクト(特に何千ものオブジェクトを作成するオブジェクト)を自動リリースしないことは完全に有効であり、場合によっては望ましいことです。さらに、プールを調べて何が入っているのか、何が入っていないのかを確認したり、各オブジェクトを突いて死んでいるかどうかを確認したりすることはできません。
オブジェクトがCocoa/Objective-Cで適切に解放/保持されていることを確認するために、たとえばOCUnitを使用して単体テストをどのように記述しますか?
最善の方法は、に設定NSZombieEnabledしYESて、setUpの以前の値を復元することtearDownです。これは、過剰リリース/不足保持をキャッチしますが、いかなる種類のリークもキャッチしません。
メモリ管理を徹底的にテストする単体テストを作成できたとしても、テスト可能なコード(モデルオブジェクト、場合によっては特定のコントローラー)しかテストできないため、不完全です。ビューコード、ペン先での参照、特定のオプション(「閉じたときにリリース」が頭に浮かぶ)などが原因で、アプリケーションにリークやクラッシュが発生する可能性があります。
アプリケーションにメモリバグがないことを確認するために作成できるアプリケーション外テストはありません。
とは言うものの、あなたが想像しているようなテストは、それが自己完結型で自動である場合、すべてをテストできなくても、かなりクールです。ですから、私が間違っていて、方法があることを願っています。