これまでどのようなシチュエーションで使用されていたのか-retainCount
、最終的にはどのような問題が発生するのか教えていただきたいです。
ありがとう。
これまでどのようなシチュエーションで使用されていたのか-retainCount
、最終的にはどのような問題が発生するのか教えていただきたいです。
ありがとう。
-retainCount
有用なことは何も教えてくれないので、絶対に使用しないでください。FoundationおよびAppKit/UIKitフレームワークの実装は不透明です。何が保持されているのか、なぜ保持されているのか、誰が保持しているのか、いつ保持されているのかなどはわかりません。
例えば:
[NSNumber numberWithInt:1]
でしょう。そうでretainCount
はありません。2です。@"Foo"
でしょう。そうでretainCount
はありません。1152921504606846975です。[NSString stringWithString:@"Foo"]
でしょう。そうでretainCount
はありません。繰り返しますが、1152921504606846975です。基本的に、何でもオブジェクトを保持できる(したがってそのオブジェクトを変更できるretainCount
)ため、またアプリケーションを実行するほとんどのコードのソースがないため、オブジェクトretainCount
は無意味です。
オブジェクトの割り当てが解除されない理由を突き止めようとしている場合は、Instrumentsのリークツールを使用してください。オブジェクトの割り当てが早すぎる理由を突き止めようとしている場合は、Instrumentsのゾンビツールを使用してください。
ただし、は使用しないでください-retainCount
。それは本当に価値のない方法です。
編集
皆さん、http://bugreport.apple.comにアクセスして、廃止をリクエストしてください-retainCount
。それを求める人が多ければ多いほど良いです。
編集#2
更新として、[NSNumber numberWithInt:1]
現在はretainCount
9223372036854775807になっています。コードが2であると期待していた場合、コードは壊れています。
真剣に。やらないでください。
メモリ管理のガイドラインに従ってalloc
、new
またはcopy
(または最初に呼び出したもの)のみを解放しますretain
。
@bbum はSO のここで最もよく言ったし、彼のブログでさらに詳しく述べた。
自動解放されたオブジェクトは、-retainCount をチェックしても情報がなく、誤解を招く可能性がある 1 つのケースです。保持カウントは、オブジェクトに対して -autorelease が呼び出された回数、したがって現在の autorelease プールがドレインされたときにオブジェクトが解放される回数については何もわかりません。
「Instruments」を使用してチェックすると、retainCounts は非常に便利です。
「allocations」ツールを使用して、「Record reference counts」がオンになっていることを確認してください。これにより、任意のオブジェクトに移動して、retainCount 履歴を確認できます。
alloc と release を組み合わせることで、何が起こっているのかをよく把握でき、多くの場合、何かがリリースされていないという困難なケースを解決できます。
iOS の初期のベータ リリースでバグを発見したことも含め、これでがっかりしたことはありません。
NSObjectに関する Apple のドキュメントをご覧ください。質問の内容はほぼ網羅されています。
要するに、独自の参照カウント システムを実装していない限り、retainCount はおそらく役に立たないでしょう (実装しないことはほぼ保証できます)。
Apple自身の言葉では、retainCountは「通常、メモリ管理の問題のデバッグには価値がありません」.
もちろん、retainCount メソッドをコードで使用するべきではありません。その値の意味は、オブジェクトに適用された自動解放の数に依存し、予測できないからです。ただし、デバッグには非常に便利です。特に、メイン イベント ループの外側で Appkit オブジェクトのメソッドを呼び出すコードでメモリ リークを探している場合は、非推奨にすべきではありません。
あなたは自分の主張を主張しようとして、その価値の不可解な性質を真剣に誇張しました. 常に参照カウントであるとは限らないのは事実です。フラグに使用される特別な値がいくつかあります。たとえば、オブジェクトの割り当てを解除してはならないことを示すために使用されます。1152921504606846975 のような数値は、16 進数で書き込んで 0xffffffffffffffff を取得するまでは非常に不思議に見えます。9223372036854775807 は 16 進数で 0x7ffffffffffffff です。そして、retainCount を 1 秒あたり 100,000,000 回インクリメントすると仮定すると、retainCount をより大きな数値と同じくらい高くするには、ほぼ 3000 年かかることを考えると、誰かがこれらのような値をフラグとして使用することを選択することはそれほど驚くべきことではありません。
それを使用すると、どのような問題が発生する可能性がありますか? オブジェクトの保持カウントを返すだけです。私はそれを呼んだことはありませんし、そうする理由も思いつきません。ただし、割り当てが解除されないように、シングルトンでオーバーライドしました。
アプリが起動して実行され、何か有用なことが行われるまで、メモリ リークについて心配する必要はありません。
それができたら、Instruments を起動してアプリを使用し、メモリ リークが実際に発生するかどうかを確認します。ほとんどの場合、自分でオブジェクトを作成し (つまり自分が所有している)、作業が終わった後にそれを解放するのを忘れていました。
コードを書いているときにコードを最適化しようとしないでください。アプリを実際に通常どおり使用する場合、メモリ リークや時間がかかりすぎる可能性があるという推測はしばしば間違っています。
alloc などを使用してオブジェクトを作成する場合など、正しいコードを書いてみてください。その後、適切にリリースするようにしてください。
コード内では絶対に使用しないでください。ただし、デバッグ時に役立つことは間違いありません