开发者

UITableView's NSString memory leak on iphone when encoding with NSUTF8StringEncoding

my UITableView have serious memory leak problem only when the NSString is NOT encoding with 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(dat开发者_开发百科abase, 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);

}

when i change the line

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

to

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

the memory leak is gone

i tried NSString stringWithUTF8String and it still leak. i've also tried:

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

and the problem remains, the leak occur when u start scrolling the tableview.

i've actually tried other encoding and it seems that only NSASCIIStringEncoding works(no memory leak)

if i did not scroll the tableview before i close the view, it's no leak at all. actually listOfInfo itself didn't leak, since the leak never occur when i remove the line

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

any idea/workaround how to get rid of this problem?

note: i do have

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

on dealloc already


The leak in your program is actually here:

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

You are allocating the dictionary and never releasing it, so it leaks. You should write:

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

or

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

Since this dictionary contains your strings, the string leaks along with the dictionary. Changing to NSASCIIStringEncoding doesn't fix this leak, it probably just disguises it (since the string will need to be subsequently converted and Leaks might not track it to its new location) or the conversion might fail entirely (if the string can't be converted to ASCII).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜