0

計測器でいくつかのメモリ プロファイリングを行っていますが、適切なメモリ管理を行っているように見えるコードがあるように感じます。しかし、楽器は私が漏れていると確信しており、漏れをなくす方法がわかりません。

私のEvent.hには私が持っています。


@property (nonatomic, copy) NSString *organizer;
@property (nonatomic, copy) NSString *type;
@property (nonatomic, retain) NSDate *startTime;
@property (nonatomic, retain) NSDate *endTime;
@property (nonatomic, copy) NSString *coverCharge;
@property (nonatomic, copy) NSString *ageLimit;
@property (nonatomic, copy) NSString *dressCode;
@property (nonatomic, copy) NSString *venueName;
@property BOOL attendingFlag;

それらはすべてdeallocで解放されます


- (void) dealloc {
    [type release];
    [organizer release];
    [startTime release];
    [endTime release];
    [coverCharge release];
    [ageLimit release];
    [dressCode release];
    [venueName release];
    [super dealloc];
}   

そして、私のファクトリークラスでは、


-(Event*) getEvent:rs {
    Event *event = [[Event alloc] init];
    event.objId = [NSNumber numberWithInt:[rs intForColumn:DATABASE_EVENT_ID_FIELD]];
    event.name= [rs stringForColumn:DATABASE_EVENT_NAME_FIELD];
    event.organizer = [rs stringForColumn:DATABASE_EVENT_ORGANIZER_FIELD];
    event.type = [rs stringForColumn:DATABASE_EVENT_TYPE_FIELD];
    event.desc= [rs stringForColumn:DATABASE_EVENT_DESCRIPTION_FIELD];
    event.venueName = [rs stringForColumn:DATABASE_EVENT_VENUE_NAME_FIELD];
    event.coverCharge= [rs stringForColumn:DATABASE_EVENT_COVER_CHARGE_FIELD];
    event.dressCode = [rs stringForColumn:DATABASE_EVENT_DRESS_CODE_FIELD];
    event.ageLimit = [rs stringForColumn:DATABASE_EVENT_AGE_LIMIT_FIELD];
    event.region = [[[Region alloc] initWithIdAndName:[NSNumber numberWithInt:[rs intForColumn:DATABASE_EVENT_REGION_ID_FIELD]] name:[rs stringForColumn:DATABASE_EVENT_REGION_NAME_FIELD]] autorelease];
    event.community = [[[Community alloc] initWithIdAndName:[NSNumber numberWithInt:[rs intForColumn:DATABASE_EVENT_COMMUNITY_ID_FIELD]] name:[rs stringForColumn:DATABASE_EVENT_COMMUNITY_NAME_FIELD]] autorelease];
    event.address = [rs stringForColumn:DATABASE_EVENT_ADDRESS_FIELD];
    event.address2 = [rs stringForColumn:DATABASE_EVENT_ADDRESS2_FIELD];
    event.city = [rs stringForColumn:DATABASE_EVENT_CITY_FIELD];
    event.state = [rs stringForColumn:DATABASE_EVENT_STATE_FIELD];
    event.zip = [rs stringForColumn:DATABASE_EVENT_ZIP_FIELD];
    event.country = [rs stringForColumn:DATABASE_EVENT_COUNTRY_FIELD];
    event.phone = [rs stringForColumn:DATABASE_EVENT_PHONE_FIELD];
    event.webpage = [rs stringForColumn:DATABASE_EVENT_WEBPAGE_FIELD];

    return [event autorelease];
}

上記よりも多くの属性をイベントに設定していることに気付くかもしれません。これは、より一般的な別のエンティティを拡張する Event があるためです。そのコードを投稿しなかった理由は、楽器によると、Event クラス自体のセッターでさえ漏れているからです。

インストルメントは、イベント割り当てにリークがあり、getEvent セレクターのすべての行に別のリークがあると訴えています。rs は、私がアプリ全体で使用しているライブラリ (FMDB) の結果セット オブジェクトであり、これがこれらのリークが検出される唯一のエンティティであるように思われるので、それが問題ではないと確信しています。私は実際にこの同じライブラリを別のプロジェクトで最近使用しましたが、それによるリークはなかったので、リークの原因から除外しました。

(a) イベント オブジェクトを返すときに、イベント オブジェクトを明らかに自動解放しています。

(b) すべてのセッターが自動解放されたオブジェクトを取得しているため、目的 c のメモリ管理ドキュメントで推奨されているように、保持カウントのみを増やしています。

alloc 行とそれに続くほぼすべての行がリークしている理由は何ですか?

4

1 に答える 1

1

答えは、他の場所のコードが Event オブジェクトを保持しているということです。リークは、リークされたメモリが作成された場所を示すことしかできません。リークは、作成後にオブジェクトを正しく解放するために書かれているはずのコードを示すことはできません!

Event オブジェクトがリークしているため、他の行はすべてリークとしてマークされます。

すべきことは、Leaks に加えて Allocations インストゥルメントを追加し、「参照カウントを記録する」ように設定されていることを確認することです (時間グラフの Allocations バーに小さな (i))。次にアプリを起動し、リークを観察します。次に、割り当てツールを選択し、「作成され、まだ生きている」を選択し、まだ存在するイベント オブジェクトを検索します。

アドレスの横にある矢印をクリックすると、そのオブジェクトのすべての保持と解放のリストが表示されます。通常は、後で解放する必要があったが解放しなかったオブジェクトを保持していたものを把握できます。

于 2011-04-10T06:08:15.407 に答える