8

オブジェクトが自動解放された回数を知りたいです。オブジェクトが自動解放されたかどうかを知るのは一般的に簡単なほど十分長い間客観的 c を使用してきましたが、メモリと保持カウントを扱う質問を常に目にします。ある時点で、答えは常に「オブジェクトのretainCountを信頼することはできません」で終わります-これには同意しますが、オブジェクトが自動解放された回数を判断できれば、追加した場合、retainCountを実際に信頼できます次のようなカテゴリ:

@interface NSObject (NSObject_MemoryDebugging)
- (NSUInteger) autoReleaseCount;
- (NSUInteger) retainCountWithAutoRelease;
@end

@implementation]
/** Determine how many times this object has been marked for autorelease **/
- (NSUInteger) autoReleaseCount;
{
   // ??? not sure how to figure this out.
   return 0;
}

 - (NSUInteger) retainCountWithAutoRelease
{
   NSUInteger retainCount = [self retainCount];
   NSUInteger autoReleaseCount = [self getAutoReleaseCount];  // ???
   return retainCount - autoReleaseCount;
}
@end

通常、コピー中に保持カウントが増加するため、不変型の例外は依然としてあります。

私が提案していないこと

プロダクションコードでretainCountを使用するためにこの答えを求めているわけではありません。ただし、これはメモリの問題をデバッグする人にとっては価値があると思います。

プログラマーはオブジェクトが自動解放された回数を気にするべきではないので、この質問を嫌う人もいると思います。コーディングは、割り当て、保持、コピー、リリースに伴う新規作成、ストーリーの終わりのバランスをとることがすべてであるべきです。ただし、これのポイントは、人々が頭を叩くのを助けることです。 [NSObject retainCount]多くの人を燃やします、そしてこの質問への答えはかなりクールです.

オブジェクトが自動解放された回数を判断する方法があると確信しています。私はそれが何であるかわからないので、質問です。

同様の質問を参照してください: Objective-c の NSAutoreleasePool 内のオブジェクト

編集


皆様、ご回答ありがとうございます。これは面白いと思うかもしれません => Ariel は、GNUStep の Cocoa の実装、具体的には NSAutoReleasePool に+(NSUInteger)autoreleaseCountForObject:(id)anObject というメソッドがあることを指摘しました。このメソッドは遅く、呼び出し元のスレッドの NSAutoReleasePools からの自動解放カウントのみを返します。それでも...そこにあるのは興味深いです。ドキュメントは、実際にはデバッグにのみ役立つと述べています。これは、私が Cocoa フレームワークで何らかの方法で見つけたい (または可能性を見つけたい) ことです。

自動解放カウントを取得できたとしても、より優れたツール (ゾンビ、リーク、静的アナライザー) が存在するという回答に同意します。

4

4 に答える 4

1

NSAutoreleasePool+(void)showPoolsには、以前はまったく知らなかったメソッドがあります。これは役に立つかもしれません。Is there a way to inspect an NSAutoreleasePool's objects?も参照してください。. そのスレッドで、KennyTM は (コメントで) 言った:

コンテンツは stderr に出力されるため、ストリームを再度開いて解析し、すべてのポインターを取得できます。

参考までに、Foundation フレームワークに対して class-dump を使用して NSAutoreleasePool の詳細を確認したところ、次のようになりました。

@interface NSAutoreleasePool : NSObject {
    void *_token;
    void *_reserved3;
    void *_reserved2;
    void *_reserved;
}

+ (void)addObject:(id)arg1;
+ (id)allocWithZone:(struct _NSZone *)arg1;
+ (void)showPools;
+ (void)releaseAllPools;
+ (unsigned int)autoreleasedObjectCount;
+ (unsigned int)topAutoreleasePoolCount;
+ (BOOL)autoreleasePoolExists;
+ (void)enableRelease:(BOOL)arg1;
+ (void)enableFreedObjectCheck:(BOOL)arg1;
+ (unsigned int)poolCountHighWaterMark;
+ (void)setPoolCountHighWaterMark:(unsigned int)arg1;
+ (unsigned int)poolCountHighWaterResolution;
+ (void)setPoolCountHighWaterResolution:(unsigned int)arg1;
+ (unsigned int)totalAutoreleasedObjects;
+ (void)resetTotalAutoreleasedObjects;
- (id)init;
- (void)drain;
- (oneway void)release;
- (id)initWithCapacity:(unsigned int)arg1;
- (void)addObject:(id)arg1;
- (id)retain;
- (unsigned int)retainCount;
- (id)autorelease;
- (void)dealloc;
@end

私が尋ねた質問の詳細というよりも、回答のように見えたので、これを回答として追加しました。

于 2011-09-23T15:15:06.430 に答える
0

そこで行わ-(id)autorelease;れるオブジェクトを追加する作業として、メソッドをオーバーライドする必要があるようです。そんな感じ:NSAutoreleasePool

-(id)autorelease{
    _isAutoreleased = YES;  //some BOOL member initialized to NO and returned on -(BOOL)isAutoreleased;
    [NSAutoreleasePool  addObject:self];
    return self;
}

このリンクも見てください

于 2011-09-22T15:21:28.263 に答える