いつ-retainCountを使用するのですか?


110

-retainCountこれまでにどのような状況で使用しましたか、そして最終的にそれを使用して発生する可能性のある問題について知りたいのですが。

ありがとう。


5
を使用しないでください-retainCount
holex 2013年

3
(必要な場合を除きます。時々深刻な誤解を招く可能性があることを理解している限り、何が起こっているのかを理解するのに役立つことがあります。もちろん、ARCを使用している場合はまったく許可されません。)
Hot Licks

回答:


243

を使用-retainCountすることはできません。何も役に立たないからです。FoundationおよびAppKit / UIKitフレームワークの実装は不透明です。何が保持されているのか、なぜ保持されているのか、誰が保持しているのか、いつ保持されているのかなどはわかりません。

例えば:

  • あなたはそれが1で[NSNumber numberWithInt:1]あると思うでしょうretainCount。それはありません。2です。
  • あなたはそれが1で@"Foo"あると思うでしょうretainCount。それはありません。1152921504606846975です。
  • あなたはそれが1で[NSString stringWithString:@"Foo"]あると思うでしょうretainCount。それはありません。ここでも、1152921504606846975です。

基本的に、何でもオブジェクトを保持できる(したがって、オブジェクトを変更できるretainCount)ため、およびアプリケーションを実行するほとんどのコードのソースがないため、オブジェクトのretainCount意味はありません。

オブジェクトが割り当て解除されない理由を追跡する場合は、InstrumentsのLeaksツールを使用します。オブジェクトの割り当て解除が早すぎる理由を追跡する場合は、InstrumentsのZombiesツールを使用します。

ただし、は使用しないでください-retainCount。それは本当に価値のない方法です。

編集する

誰もがhttp://bugreport.apple.comにアクセスして-retainCount、廃止予定をリクエストしてください。それを求める人が多いほど良い。

編集#2

更新として、9223372036854775807 [NSNumber numberWithInt:1]retainCountが追加されました。コードが2であると予期していた場合、コードは壊れています。


4
あなたの例を@ Dave-Delongに感謝します。
Moszi

1
RetainCountは現在、シングルトンに便利です(ここで問題は、シングルトンがいかに便利かということです...)- (NSUInteger)retainCount{return NSUIntegerMax;}
Joe

8
@Joeをオーバーライドせずにシングルトンを作成できますretainCount
Dave DeLong、2011年

5
@ジョー私はそれを知っています。Googleの「objective-c singleton」は、その例があまり良い例ではない理由についてのすべての議論に対応しています。
Dave DeLong、2011年

2
私が使用する1つのこと-@DaveDeLong、これも間違っていると思うかもしれませんが、私はそうは思いません-は、deallocとinitを上書きし、それらにNSLogを(ARCを使用しても)配置することです。これは私のオブジェクトが...我々は通常の答えにしようとしている本当の問題である、deallocedか取得しているかどうかの素晴らしいアイデア提供します
ダンRosenstark

50

絶対に!

真剣に。しないでください。

メモリ管理ガイドラインに従って、自分allocnewまたはcopy(またはretain最初に呼び出したもの)のみをリリースしてください。

@bbumはここSOで、さらに詳しくは彼のブログでそれを最もよく言った。


8
あなたはあなたが記憶を数えていると思うでしょうが、あなたはそれを間違っているでしょう。
Abizern、2011年

@Abizern-そして、他の答えの1つにおけるシングルトンの状況はどうですか?
Moszi、2011年

3
これに追加するために、-retainCountInstrumentsとそのツールから(より詳細に)取得できる情報を取得できます。
Dave DeLong、2011年

3
デイブが言ったことに追加するには、オブジェクトの絶対保持カウントは実装の詳細です。オブジェクトの内部の詳細および/またはオブジェクトが渡された可能性のある他のオブジェクトの詳細の両方。呼び出しretainretainretainautorelease, 自動解放は、autorelease例えば、UIKitのAPIを使用してオブジェクトを渡すの完全に有効な結果である可能性があります。
bbum

2
@ d11wtq RetainCount ever == 0の場合、特異性が達成されました!
bbum

14

自動解放されたオブジェクトは、-retainCountのチェックが有益ではなく、誤解を招く可能性がある1つのケースです。保持カウントは、オブジェクトに対して-autoreleaseが呼び出された回数については何も通知しないため、現在の自動解放プールが空になったときにオブジェクトが解放される回数を示します。


1
ありがとう-これは良い点です。これは、一般的に「しない」以外に、retainCountを使用しない理由が実際に説明されている最初の回答です。
Moszi、2011年

1
@Moszi:あなたの質問は「retainCountをいつ使うのか?」—その質問をするつもりがなかった場合は、別の質問をするべきでした。
Chuck

@chuck-実際、私は「いつ使用するか」に興味がありましたが、すべての答えは「決して」ではないようです...しかし、私はあなたが正しいと思います。質問を2日間開いたままにします。他に回答がない場合は、「絶対にしない」を回答として受け入れます。
Moszi

10

私はない「楽器」を使用してチェックするときに非常に便利retainCountsを見つけます。

「割り当て」ツールを使用して、「レコード参照カウント」がオンになっていることを確認します。任意のオブジェクトに移動して、retainCount履歴を確認できます。

allocsとreleasesをペアにすることで、何が起こっているかをよく把握し、リリースされていない困難なケースを解決できることがよくあります。

これは私を失望させることは決してありません-iOSの初期ベータリリースでバグを見つけることを含みます。


5

NSObjectに関するAppleのドキュメントを見てください。それはあなたの質問をほとんどカバーしています: NSObject maintainCount

要するに、独自の参照カウントシステムを実装していない限り、retainCountはおそらく役に立たないでしょう(私はあなたがそうしないことをほぼ保証できます)。

Apple自身の言葉で言えば、retainCountは「通常、メモリ管理の問題をデバッグすることに意味はありません」。


まずはお答えいただきありがとうございます。通常、この質問に対する人々の反応は「決して」ありません。(答えを見てください)。実際、「デバッグに値がない」とは、「絶対に」という意味ではありません。だから私の質問は、なぜそれを使用しないという強い気持ちがあるのですか(たとえば、シングルトン実装では-答えの1つです)?
Moszi、2011年

何のためにそれを使っているかについてもっと情報を提供する必要があると思います。Appleの提案に従い、retainCountをオーバーライドして独自の参照カウントシステムを実装することもできます。しかし、実際には、それを見ることは決してありません(とにかく私が持っていることはありません)。強い反応は、一般的にApple自身(メールグループ、ドキュメント、開発者フォーラムなど)で、retainCountをそのままにすることを提唱しているという事実から来ています。
lxt

1
@Moszi:デバッグは、ほとんどの人が価値があると考えることができる唯一の状況であるため、そこで信頼できない場合、デバッグは役に立ちません。他にどのような用途を考えていますか?
チャック

4

もちろん、retainCountメソッドをコードで使用しないでください。その値の意味は、オブジェクトに適用されている自動解放の数によって異なり、予測できないためです。ただし、デバッグには非常に役立ちます。特に、メインイベントループの外側でAppkitオブジェクトのメソッドを呼び出すコードでメモリリークを追跡する場合に役立ちます。非推奨にしないでください。

あなたの主張をするあなたの努力において、あなたは価値の不可分の性質を真剣に誇張しました。常に参照カウントであるとは限りません。フラグに使用される特別な値がいくつかあります。たとえば、オブジェクトの割り当てを解除してはならないことを示します。1152921504606846975のような数値は、16進数で書き込んで0xfffffffffffffffを取得するまで、非常に不思議に見えます。また、9223372036854775807は16進数で0x7fffffffffffffffです。そして、retainCountを1秒あたり100,000,000回インクリメントすると仮定すると、retainCountがより大きな数と同じになるまでにほぼ3000年かかることを考えると、誰かがこれらの値をフラグとして使用することを選択することはそれほど驚くべきことではありません。


3

あなたはそれを使うことからどんな問題を得ることができますか?オブジェクトの保持カウントを返すだけです。私はそれを一度も電話したことがなく、私がそうする理由を考えることができません。シングルトンでオーバーライドして、割り当てが解除されないようにしました。


2
シングルトンの場合にそれをオーバーライドする理由はありません。Foundation / CoreFoundationにはretainCount、メモリ管理に使用するコードパスがありません。
bbum

リリースはそれを使用して、deallocを呼び出す必要があるかどうかを判断しませんか?
ughoavgfhw 2011年

2
いいえ。保持/リリース/自動解放の内部実装は、CoreFoundationに深く根ざしており、実際に期待するものではありません。CoreFoundationソース(入手可能)を入手して見てください。
bbum

3

アプリが稼働して有用な何かを実行するまで、メモリリークを心配する必要はありません。

それが終わったら、Instrumentsを起動してアプリを使用し、メモリリークが本当に発生するかどうかを確認します。ほとんどの場合、自分でオブジェクトを作成し(したがって、それを所有している)、完了後にオブジェクトを解放するのを忘れていました。

コードを書いているときにコードを最適化しようとしないでください。実際にアプリを実際に使用する場合、メモリリークや時間がかかりすぎると思われることがよくあります。

たとえば、allocなどを使用してオブジェクトを作成する場合は、適切なコードをリリースしてください。


0

コードでは絶対に使用しないでください。ただし、デバッグ時には確実に役立ちます。


0

コードで-retainCountを使用しないでください。ただし、使用した場合、ゼロが返されることはありません。その理由を考えてください。:-)


0

Daveの投稿で使用されている例はNSNumberとNSStrings ...なので、UIViewsなどの他のクラスを使用すると、正しい答えが得られると確信しています(保持数は実装によって異なり、予測可能です)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.