web-dev-qa-db-ja.com

ARCモードで参照カウントを確認するにはどうすればよいですか?

デバッガーの下で[myVar retainCount]を使用して、特にカスタムdeallocを持たないvarの場合、一部の変数に予想される保持カウントがあることを確認していました。

ARCモードでこれをどのように行いますか?メモリリークがないことをどのように確認しますか?

注:ARCはこれを処理する必要があることを理解していますが、人生は完璧とはほど遠いものであり、実際にはサードパーティライブラリ(retain?を使用)によって割り当てられ、割り当て解除されないオブジェクトがあります。

私がこれを行う画像:

MyObj *myObj=[[MyObj alloc] init];

それから私は電話する

[somethingElse doSomethingWithMyObj:myObj];

そして後で

myObj=NULL;

私のプログラムが正常に動作している場合、myObjが破壊されることを期待していますが、そうではないようです...

特に何かが私によって管理されていない場合、どうすればこれを追跡できますか?

さて、ツールについて:Macを再起動せずにゼロから起動せずに(5 Megの)Macでメモリツールを実行するのは非常に難しいようです。これは本当に迷惑です!プログラムが開始する前でも機器がクラッシュし続けるので、別の解決策はありますか?

34
tomsoft

ARCの下でも、Objective-CオブジェクトでCFGetRetainCountを使用できます。

_NSLog(@"Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)myObject));
_

これはnotですが、デバッグには特に便利ですが、 他の場所で十分に説明されている理由により です。オブジェクトが保持および解放される場所を理解する必要がある場合は、 this answer をご覧ください。

保持カウントを調べることが実際に有用であることがわかった唯一のケースは、割り当て解除されているオブジェクトを保持して自動解放する、deallocメソッドの場合です。これにより、後で自動解放プールが空になったときにクラッシュが発生します。各メッセージの前後で保持カウントを確認することにより、この原因を特定できます。このようにして、私は observationInfoメソッド (それ自体は通常デバッグにのみ役立つ)がselfを保持および自動解放することを発見しました。ただし、この種の問題でも、通常、保持変数を調べることなく、単にdeallocの本体全体を_@autoreleasepool_ブロックでラップすることで解決できます。

ただし、一部のクラスの実装については、保持カウントを使用して学習できます。 (娯楽または好奇心のためにのみこれを行ってください!実動コードで文書化されていない実装の詳細に頼らないでください!)

たとえば、mainの_@autoreleasepool_内ですぐにこれを試してください。

_NSNumber *n0 = [[NSNumber alloc] initWithInt:0];
NSLog(@"0 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef)n0));
// Prints 2 in my test
_

したがって、NSNumberはいくつかのインスタンスをキャッシュ(または少なくとも再利用)する可能性があります。しかし、他の人ではありません:

_n0 = [[NSNumber alloc] initWithInt:200];
NSLog(@"n0 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef) n0));
// Prints 1 - I am the sole owner of this instance.  There could be weak
// or unretained references to it, but no other strong references.

NSNumber *n1 = [[NSNumber alloc] initWithInt:200];
NSLog(@"n1 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef) n1));
// Prints 1 again.  New instance with same value as prior instance.
// You could of course compare pointers to see that they are separate
// instances.
_

NSNumberを初期化しないと、allocがシングルトンを返すことさえ発見できます。

_n1 = [NSNumber alloc];
NSLog(@"n1 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef) n1));
// Prints -1.
_

NSNumberの詳細については、 http://opensource.Apple.com にあるCore Foundationソースコードを参照することでも学習できます。ただし、 Core Foundationのオブジェクトとフリーブリッジされていないオブジェクトの保持カウントを確認しますか?)

99
rob mayoff

あなたはしません。 ARCはメモリ管理を処理し、retainCountを呼び出すことはできません。たとえそれが表示されていても、返される数値は意味がありません。必要に応じて、Leaks and Allocationsインストゥルメントを使用してインストゥルメントでメモリプロファイリングを行う必要があります。これは、アプリケーションがメモリをどのように割り当てているかを調べて確認し、そこでメモリの不適切な使用を見つける最良の方法です。

41
Colin Wheeler

ARCの有無にかかわらず、retainCountを決して使用しないでください。

-retainCount?を使用する場合

31
UIAdam

Instrumentsを使用し、「Objects List」にいる間にクラス名またはポインターアドレスを検索して、追跡するオブジェクトを見つけます。

見つけたら、インスタンスの公開矢印を押します。これにより、保持とリレースの履歴ビューが表示されます。

右側の詳細ビューを展開すると、各保持/解放のコールスタックも表示されます。

Instruments showing object history and callstack detail

15
Henrik Hartz

唯一の方法は、割り当てツールを使用してアプリケーションをプロファイルすることだと思います。情報記述子(左ペインの[割り当て]の横にある 'i')をクリックして、[参照カウントの記録]をクリックする必要があります。その後、アプリのプロファイルを作成し、調べたい特定のクラスを検索できます。そこから、クラスの各インスタンスの[拡張詳細]ペインで保持カウントを見つけることができます。

また、Leaksを使用してこれを行うこともできます(これはAllocationsインストゥルメントのバリエーションだと思います)。

3
Aaron Hayman

オブジェクトのretainCount?を取得します

ブレークポイントを作成し、以下のコマンドを入力するだけで、オブジェクトのretainCountを取得できます

po object.retainCount
2
Jason Yu

あなたはしません。 Apple ARCはあなたのためにそれを処理するので、あなたがする必要はないと言う。

0
Darren