内存泄漏 - 从包含自定义对象的类方法返回NSMutableArray

问题描述:

我正在使用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]); 
} 

此方法为函数的迭代调用创建内存泄漏。 请建议泄漏和解决方案的原因。

  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

你应该颠倒的几行代码:

arr = nil; 
[arr release]; 

是这样的:发布前

[arr release]; 
arr = nil;