Утечка памяти USSable строки UITableView на iphone при кодировании с NSUTF8StringEncoding - PullRequest
0 голосов
/ 22 марта 2010

Мой UITableView имеет серьезную проблему утечки памяти, только когда строка NSString НЕ кодируется с NSASCIIStringEncoding.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"cell";
    UILabel *textLabel1;
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
        textLabel1 = [[UILabel alloc] initWithFrame:CGRectMake(105, 6, 192, 22)];

        textLabel1.tag = 1;
        textLabel1.textColor = [UIColor whiteColor];
        textLabel1.backgroundColor = [UIColor blackColor];
        textLabel1.numberOfLines = 1;
        textLabel1.adjustsFontSizeToFitWidth = NO;
        [textLabel1 setFont:[UIFont boldSystemFontOfSize:19]];
        [cell.contentView addSubview:textLabel1];
        [textLabel1 release];

    } else {
        textLabel1 = (UILabel *)[cell.contentView viewWithTag:1];
    }

    NSDictionary *tmpDict = [listOfInfo objectForKey:[NSString stringWithFormat:@"%@",indexPath.row]];

    textLabel1.text = [tmpDict objectForKey:@"name"];

    return cell;
}

-(void) readDatabase {
    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDir = [documentPaths objectAtIndex:0];
    databasePath = [documentsDir stringByAppendingPathComponent:[NSString stringWithFormat:@"%@",myDB]];
    sqlite3 *database;

    if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {

        const char sqlStatement = [[NSString stringWithFormat:@"select id,name from %@ order by orderid",myTable] UTF8String];
        sqlite3_stmt *compiledStatement;
        if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
            while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
                NSString *tmpid = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];


                NSString *tmpname = [NSString stringWithCString:(const char *)sqlite3_column_text(compiledStatement, 1) encoding:NSUTF8StringEncoding];


                [listOfInfo setObject:[[NSMutableDictionary alloc] init] forKey:tmpid];
                [[listOfInfo objectForKey:tmpid] setObject:[NSString stringWithFormat:@"%@", tmpname] forKey:@"name"];


            }
        }
        sqlite3_finalize(compiledStatement);

        debugNSLog(@"sqlite closing");

    }
    sqlite3_close(database);

}

, когда я изменяю строку

NSString *tmpname = [NSString stringWithCString:(const char *)sqlite3_column_text(compiledStatement, 1) encoding:NSUTF8StringEncoding];

на

NSString *tmpname = [NSString stringWithCString:(const char *)sqlite3_column_text(compiledStatement, 1) encoding:NSASCIIStringEncoding];

утечка памяти исчезла

Я попробовал NSString stringWithUTF8String, и она все еще утечка.я также пробовал:

NSData *dtmpname = [NSData dataWithBytes:sqlite3_column_blob(compiledStatement, 1) length:sqlite3_column_bytes(compiledStatement, 1)];
NSString *tmpname = [[[NSString alloc] initWithData:dtmpname encoding:NSUTF8StringEncoding] autorelease];

и проблема остается, утечка происходит, когда вы начинаете прокручивать просмотр таблицы.

Я на самом деле пробовал другое кодирование, и кажется, что работает только NSASCIIStringEncoding(нет утечки памяти)

Если я не прокручивал табличное представление перед тем, как закрыть представление, это вообще не утечка.на самом деле сам listOfInfo не просочился, поскольку утечка никогда не происходит, когда я удаляю строку

textLabel1.text = [tmpDict objectForKey:@"name"];

Любая идея / способ обойти эту проблему?

примечание: у меня есть

for (id theKey in listOfInfo) {
   [[listOfInfo objectForKey:theKey]  release];
}
[listOfInfo release];

уже на dealloc

1 Ответ

3 голосов
/ 22 марта 2010

Утечка в вашей программе на самом деле здесь:

[listOfInfo setObject:[[NSMutableDictionary alloc] init] forKey:tmpid];

Вы выделяете словарь и никогда не выпускаете его, поэтому он вытекает.Вы должны написать:

[listOfInfo setObject:[[[NSMutableDictionary alloc] init] autorelease] forKey:tmpid];

или

[listOfInfo setObject:[NSMutableDictionary dictionary] forKey:tmpid];

Так как этот словарь содержит ваши строки, строка просачивается вместе со словарем.Изменение на NSASCIIStringEncoding не устраняет эту утечку, возможно, она просто маскирует ее (поскольку впоследствии необходимо будет преобразовать строку, а Leaks может не отследить ее до ее нового местоположения), или преобразование может завершиться неудачно (если строка может 'не может быть преобразовано в ASCII).

...