2011-03-09 61 views
1

我正在使用DBManager類從SQlite數據庫中重新運行數據。該類包含通過從數據庫獲取MutableArray來返回的方法。像波紋管..內存泄漏 - 從包含自定義對象的類方法返回NSMutableArray

+ (NSMutableArray *) getSaleForYear : (NSString *) year { 

    if ([DBManager openDBConnection]) { 

     NSMutableArray * sales = [[NSMutableArray alloc] initWithCapacity:1]; 

     const char *q = "SELECT sales, quarter FROM sale where year like ? order by quarter"; 
     sqlite3_stmt *selectstmt; 
     if (sqlite3_prepare_v2(database, q, -1, &selectstmt, NULL) == SQLITE_OK) { 

      if(sqlite3_bind_text(selectstmt, 1, [year UTF8String] , -1, SQLITE_TRANSIENT) != SQLITE_OK){ 
       NSLog(@"bind error : %@", [NSString stringWithUTF8String: sqlite3_errmsg(database)]); 
       return nil; 
      } 

      while(sqlite3_step(selectstmt) == SQLITE_ROW) { 
       float sale = sqlite3_column_double(selectstmt, 0); 
        //NSString * quarter = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)]; 
       NSString * quarter = [[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)]; 

       ChartData * b1 = [[ChartData alloc] initwithdata:quarter y:sale]; 
       [sales addObject:b1]; 
       [b1 release]; 
       [quarter release]; 
      } 
     } 

     sqlite3_finalize(selectstmt); 
     [DBManager closeDBConnection]; 
     return [sales autorelease]; 
    }else { 
     return nil; 
    } 
} 

我打電話來像法。

- (IBAction) getData { 

    NSLog(@"getdata"); 

    if (arr != nil) { 
     for (ChartData * cd in arr) { 
      [cd release]; 
     } 
     arr = nil; 
     [arr release]; 
    } 

    arr = [[DBManager getSaleForYear:@"2010-11"] copy]; 
    NSLog(@"count %d ", [arr count]); 
} 

此方法爲函數的迭代調用創建內存泄漏。 請建議泄漏和解決方案的原因。

回答

2
  1. 你設置arr = nil,這個[arr release]沒有效果
  2. 你必須不循環數組並釋放每個對象(請參見下面的fluchtpunkt註釋)。
  3. 無需檢查arr == nil發送消息至nil有效。

我會寫:

- (IBAction)getData { 
    NSLog(@"getdata"); 

    [arr release]; 

    arr = [[DBManager getSaleForYear:@"2010-11"] copy]; 
    NSLog(@"count %d ", [arr count]); 
} 
+0

第二點應該是 「你不能循環......」。當外部數組被釋放時,每個對象將被從數組中移除並且會得到另一個釋放呼叫。但它已經手動發佈。 - >內存異常 – 2011-03-09 09:39:37

+0

是的,它不清楚。編輯。 – Jilouc 2011-03-09 09:43:36

+0

謝謝,我添加的那個循環只是爲了測試它是否能解決我的問題。由於我無法看到Chartdata的dealloc僅被稱爲'[arr release]' – 2011-03-09 10:12:51

1

你應該顛倒的幾行代碼:

arr = nil; 
[arr release]; 

是這樣的:發佈前

[arr release]; 
arr = nil;