0

I have an application that uses data queries and displays them in a UITableView. So far so good, I can access the SQLite database and display the data in the table but after a short period of use of my app memory Received a notice of warning. Level = 1 and closed. Using analysis tools in the search I noticed that my app data consumes a reasonable amount of memory.

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section  {

    tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;

    return [count count];
}

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

    iMapDadosClientes *dadosClientes = (iMapDadosClientes *)[count objectAtIndex:indexPath.row];

    NSString *myIdent = @"myIdent";

    iMapGrid *grid = (iMapGrid *)[tableView dequeueReusableCellWithIdentifier:myIdent];

    tvDadosClientes.autoresizesSubviews = YES;

    if (grid == nil) {

        grid = [[[iMapGrid alloc] initWithFrame:CGRectZero reuseIdentifier:myIdent] autorelease];

        UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(0.0, 0, 50.0, tableView.rowHeight)] autorelease];

        [grid addColumn:60];

        label.tag = TAG_1; 
        label.font = [UIFont systemFontOfSize:14.0]; 
        label.text = dadosClientes.cod;
        label.textAlignment = UITextAlignmentRight; 
        label.textColor = [UIColor blackColor]; 
        label.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight; 

        [grid.contentView addSubview:label]; 

        label =  [[[UILabel alloc] initWithFrame:CGRectMake(70.0, 0, 20.0, tableView.rowHeight)] autorelease]; 

        [grid addColumn:100];

        label.tag = TAG_2; 
        label.font = [UIFont systemFontOfSize:14.0]; 
        label.text = dadosClientes.loja;
        label.textAlignment = UITextAlignmentCenter; 
        label.textColor = [UIColor blackColor]; 
        label.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight; 

        [grid.contentView addSubview:label]; 

        label =  [[[UILabel alloc] initWithFrame:CGRectMake(110.0, 0, 350.0, tableView.rowHeight)] autorelease]; 

        [grid addColumn:470];

        label.tag = TAG_3; 
        label.font = [UIFont systemFontOfSize:14.0]; 
        label.text = dadosClientes.nome;
        label.textAlignment = UITextAlignmentLeft; 
        label.textColor = [UIColor blackColor]; 
        label.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight; 

        [grid.contentView addSubview:label]; 

        label =  [[[UILabel alloc] initWithFrame:CGRectMake(480.0, 0, 240.0, tableView.rowHeight)] autorelease]; 

        [grid addColumn:730];

        label.tag = TAG_4; 
        label.font = [UIFont systemFontOfSize:14.0]; 
        label.text = dadosClientes.mun;
        label.textAlignment = UITextAlignmentLeft; 
        label.textColor = [UIColor blackColor]; 
        label.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight; 

        [grid.contentView addSubview:label]; 

        label =  [[[UILabel alloc] initWithFrame:CGRectMake(740.0, 0, 20.0, tableView.rowHeight)] autorelease]; 

        [grid addColumn:768];

        label.tag = TAG_5; 
        label.font = [UIFont systemFontOfSize:14.0]; 
        label.text = dadosClientes.est;
        label.textAlignment = UITextAlignmentCenter; 
        label.textColor = [UIColor blackColor]; 
        label.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight; 

        [grid.contentView addSubview:label]; 
    }

    UILabel *label_1 = (UILabel *)[grid.contentView viewWithTag:TAG_1];
    label_1.text = dadosClientes.cod;

    UILabel *label_2 = (UILabel *)[grid.contentView viewWithTag:TAG_2];
    label_2.text = dadosClientes.loja;

    UILabel *label_3 = (UILabel *)[grid.contentView viewWithTag:TAG_3];
    label_3.text = dadosClientes.nome;

    UILabel *label_4 = (UILabel *)[grid.contentView viewWithTag:TAG_4];
    label_4.text = dadosClientes.mun;

    UILabel *label_5 = (UILabel *)[grid.contentView viewWithTag:TAG_5];
    label_5.text = dadosClientes.est;

    return grid;
}

- (void) getInitialDataToDisplay:(NSString *)dbPath {

    count = [[NSMutableArray alloc] init];

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

        const char *sql = "select cod, loja, nome, mun, est from apsa1010;";
        sqlite3_stmt *selectstmt;

        if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) {

            while(sqlite3_step(selectstmt) == SQLITE_ROW) {

                iMapDadosClientes *dadosClientes = [[iMapDadosClientes alloc] cod:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 0)] loja:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)] nome:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 2)] pessoa:nil ender:nil bairro:nil mun:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 3)] est:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 4)] tel:nil bco1:nil risco:nil classe:nil lc:nil transp:nil ultCom:nil statCli:nil metr:nil salDup:nil uligTlv:nil dCompra:nil vend:nil celul:nil fax:nil email:nil contato:nil dtCada:nil priCom:nil dtNac:nil dtFunda:nil recno:nil];

                [count addObject:dadosClientes];

                [dadosClientes release];



                dadosClientes = nil;
            }
        }

        sqlite3_finalize(selectstmt);
    }
    else
        sqlite3_close(database); //Even though the open call failed, close the database connection to release all the memory.
}

- (void) finalizeStatements {

    if(database)
        sqlite3_close(database);
}

someone give me a hint of what I might be doing wrong in my code. Thank you.

bryanmac
  • 38,941
  • 11
  • 91
  • 99
user941059
  • 157
  • 4
  • 12

2 Answers2

0

Use instruments to check for leaks and memory loss due to retained but not leaked memory. The latter is unused memory that is still pointed to. Use Heapshot in the Allocations instrument on Instruments.

For HowTo use Heapshot to find memory creap, see: bbum blog

Basically there method is to run Instruments allocate tool, take a heapshot, run an intuition of your code and another heapshot repeating 3 or 4 times. This will indicate memory that is allocated and not released during the iterations.

To figure out the results disclose to see the individual allocations.

If you need to see where retains, releases and autoreleases occur for an object use instruments:

Run in instruments, in Allocations set "Record reference counts" on on (you have to stop recording to set the option). Cause the picker to run, stop recording, search for there ivar (datePickerView), drill down and you will be able to see where all retains, releases and autoreleases occurred.

Community
  • 1
  • 1
zaph
  • 111,848
  • 21
  • 189
  • 228
0

Not sure if these are your memory issues but here's some things to look at.

Always check the return codes of all sqlite calls. For example, sqlite3_finalize has a return code as does sqlite3_close. If finalize doesn't succeed (for example, busy), you may need to cleanup in close (it doesn't do it for you necessarily). Here's my close function:

if (_sqlite3)
{   
    int rc = sqlite3_close(_sqlite3);

    if (rc == SQLITE_BUSY) 
    {   
        sqlite3_stmt *stmt; 
        while ((stmt = sqlite3_next_stmt(_sqlite3, 0x00)) != 0) 
        {
            sqlite3_finalize(stmt); 
        }

        rc = sqlite3_close(_sqlite3);
    }

    if (rc != SQLITE_OK)
    {
        NSLog(@"close not OK.  rc=%d", rc);
    }

    _sqlite3 = NULL;
}

Outside of the memory issues you should look at:

  • prepare compiles the sql statement can gives you back a reference (&selectstmt in your case). You shouldn't recompile it every time. Instead, stuff away the reference and call sqlite3_reset before you use it again and don't finalize until you clean up that area of the code. That allows you to use the same compiled statement over and over from the VBL - memory should hold steady.

  • Why open and close every time? This isn't sql server client or something with a connection pool. Leave it open, re-use your compiled statements and benefit from the caches and compiled statements.

bryanmac
  • 38,941
  • 11
  • 91
  • 99