2012-01-09 60 views
0

我有一個應用程序使用數據查詢並將它們顯示在UITableView中。到目前爲止,我可以訪問SQLite數據庫並在表格中顯示數據,但在短時間使用我的應用程序內存後收到警告通知。 Level = 1並關閉。在搜索中使用分析工具,我注意到我的應用程序數據消耗了合理的內存量。查詢中的內存分配

- (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); 
} 

有人給我提示我可能在我的代碼中做錯了什麼。謝謝。

回答

0

不知道這些都是你的內存問題,但這裏的一些事情來看待。

總是檢查所有sqlite調用的返回碼。例如,sqlite3_finalize和sqlite3_close一樣有一個返回碼。如果finalize不成功(例如,繁忙),則可能需要關閉清理(它不會爲您執行清理)。這是我的貼心的功能:

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; 
} 

外的內存問題你應該看看:

  • 準備編譯SQL語句可以讓你回到一個參考(& selectstmt你的情況)。你不應該每次重新編譯它。相反,在你再次使用它之前,先將引用放到一邊,然後調用sqlite3_reset,直到清理完該代碼的這一部分爲止。這允許你從VBL反覆使用相同的編譯語句 - 內存應該保持穩定。

  • 爲什麼每次打開和關閉?這不是sql server客戶端或連接池的東西。保持打開狀態,重新使用編譯後的語句,並從緩存和編譯語句中獲益。

0

使用儀器檢查由於保留但未泄漏的內存而導致的泄漏和內存損失。後者是尚未使用的內存,仍然指向。在樂器上的分配樂器中使用Heapshot。

至於如何使用Heapshot查找內存creap,請參見:bbum blog

基本上有方法是運行儀器分配工具,取heapshot,運行代碼的直覺和另一heapshot重複3或4次。這將指示在迭代過程中分配並未釋放的內存。

爲了弄清楚結果是否披露了個別分配。

如果你需要看到保留,發佈和自動釋放出現一個對象使用儀器:在儀器

運行,在設定「記錄的引用計數」關於分配(你必須停止記錄設置的選項)。導致選擇器運行,停止錄製,在那裏搜索ivar(datePickerView),向下鑽取,您將能夠看到所有保留,發佈和自動釋放發生的位置。