0

このコードのどこでメモリリークが発生しているのかを突き止めようとしていますか?

- (NSMutableArray *) fetchAidDetails:(NSNumber *) rowID {
    NSMutableArray *list = [[NSMutableArray alloc] init];    
    FMDatabase *db = [[FMDatabase databaseWithPath:[self dbPath]] retain];
    if(![db open]) {
        [db release];        
        return [list autorelease];
    }

    NSString *query = [NSString stringWithFormat:@"select legislative_type, legislative_name from legislative_aid where official_id = %d", rowID.unsignedIntValue];

    FMResultSet *result = [[db executeQueryWithFormat:query] retain];

    while ([result next]) {
        NSMutableDictionary *item = [[NSMutableDictionary alloc] init];        
        NSString *type = [[NSString alloc] init];
        type = [result stringForColumn:@"legislative_type"];
        [item setObject:type forKey:@"legislative_type"];
        [type release];

        NSString *party = [[NSString alloc] init];
        party = [result stringForColumn:@"legislative_name"];
        [item setObject:party forKey:@"legislative_name"];
        [party release];

        [list addObject:item];
        [item release];
    }

    [result release];
    [db close];
    [db release];

    return [list autorelease];
}

[アイテムの保持カウント] は [アイテムの解放] の前に 2 を与え、[リストの自動リリース] は参照カウントを 0 にします。ここで何か問題がありますか?

助けてください。

ありがとうございました

4

2 に答える 2

1
NSString *type = [[NSString alloc] init];
type = [result stringForColumn:@"legislative_type"];

保持カウントが 1 の NSString 'type' を作成していますが、別のオブジェクトをそれに割り当てています。最初の行を削除して、これを使用してください:

NSString *type = [result stringForColumn:@"legislative_type"];

[type release]また、自動解放された NSString を返すのでstringForColumn(少なくとも Cocoa の命名規則に従っている場合)を削除する必要があります。

于 2012-10-03T16:39:30.270 に答える
0
  • に頼らないでretainCountください。システムまたはクラスの内部コードは、オブジェクトを内部的に保持し、後で解放することができます。それは彼らの仕事であり、あなたにはわかりませんretainCount。それはリークを検索する良い方法ではありません

  • コード内で複数回、オブジェクト (この場合は an NSString) を割り当て、それを無視して、変数を他の値でオーバーライドします。

    NSString *party = [[NSString alloc] init]; // You allocate memory for an NSString object
    party = [result stringForColumn:@"legislative_name"]; // then you completely forget about it and override your party variable with a different object
    

あなたがやっていた場合、それは非常に似ています:

int i = 5;
i = 12;

もちろん、最初の値は役に立たず、必要ありません。しかし、コードの場合、使用しないこの値は、再利用されないメモリを割り当てるため、リークします。

  • 次に、影響を受けた別のオブジェクトをparty変数に送信した後、後でreleaseこの新しいオブジェクトに送信します。ただしparty、影響を受けた自動解放されたオブジェクトが既に含まれており、[result stringForColumn:xxx]コードの命名規則に従って、このメソッドは自動解放されたオブジェクトを返します。releaseしたがって、この新しいオブジェクトでを送信する必要はありません。

したがって、ループは次のようになります。

while ([result next])
{
  @autoreleasepool {
    NSMutableDictionary *item = [[NSMutableDictionary alloc] init];        
    NSString *type = [result stringForColumn:@"legislative_type"];
    [item setObject:type forKey:@"legislative_type"];

    NSString *party = [result stringForColumn:@"legislative_name"];
    [item setObject:party forKey:@"legislative_name"];

    [list addObject:item];
    [item release];
  }
}
于 2012-10-03T16:46:18.970 に答える