2010-08-18 49 views
0

修复该仪器被指示其他泄漏后,我发现自己在需要帮助找到我的浸出下面的代码:新手泄漏,我不太明白

- (无效){readHistoryFromDatabase sqlite3 *数据库;

NSMutableArray *days = [[NSMutableArray alloc] init]; 

NSInteger currentMonth; 

int noMonths = 0; 

int historyCount = 0; 

NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; 

[dateFormat setDateFormat:@"yyyy-MM-dd"]; 

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectory = [paths objectAtIndex:0]; 
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"database.sqlite"]; 

if(sqlite3_open([filePath UTF8String], &database) == SQLITE_OK) { 
    const char *sqlStatement = "select data, rata, var, strftime('%m', data) month from rates where id=?"; 
    sqlite3_stmt *compiledStatement; 

    if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) { 
     sqlite3_bind_int(compiledStatement, 1, id); 
     while(sqlite3_step(compiledStatement) == SQLITE_ROW) { 
      NSDate *data  = [dateFormat dateFromString:[NSString stringWithUTF8String:(char *) sqlite3_column_text(compiledStatement, 0)]]; 
      NSString *rata  = [NSString stringWithUTF8String:(char *) sqlite3_column_text(compiledStatement, 1)]; 
      NSString *var  = [NSString stringWithUTF8String:(char *) sqlite3_column_text(compiledStatement, 2)]; 
      NSInteger month  = sqlite3_column_int(compiledStatement, 3); 

      if ((currentMonth != month) && (historyCount > 0)) { 
       [self.rate setValue:[days copy] forKey:[NSString stringWithFormat:@"%d", noMonths]]; 

       noMonths++; 
       [days removeAllObjects]; 
       currentMonth = month; 
      } else if (historyCount == 0) { 
       currentMonth = month; 
      } 

      CHis *new = [[CHis alloc] init]; 
      new.rata = rata; 
      new.var = variatie; 
      new.month = month; 
      new.data = data; 
      historyCount++; 
      [days addObject:new]; 
      [new release]; 
     } 
     if ([days count] > 0) { 
      [self.rate setValue:[days copy] forKey:[NSString stringWithFormat:@"%d", noMonths]]; 
     } 
    } 
    sqlite3_finalize(compiledStatement); 
} 
[dateFormat release]; 
[days release]; 
sqlite3_close(database); 

}

self.rate定义是这样的:

@属性(非原子,保留)的NSMutableDictionary *率;

和在viewDidLoad中:

self.rate = [[ALLOC的NSMutableDictionary] INIT];

基本上这部分代码从数据库中读取一些速率。基于这个月,它将把NSDictionary放入一个月和一个包含费率的Array。

我不明白漏水在哪里。我知道这可能是非常简单的,但我现在正在寻找2天的解决方案.....

回答

0

在仪器中,您可以看到泄漏的来源,按扩展详细信息按钮并选择泄漏,那么您将会看到泄漏来自哪种方法和文件。

2

[[NSMutableDictionary alloc] init]返回保留计数为1的对象。然后将其分配给self.rate,这会增加保留计数(将为2)。如果您分配别的东西来self.rate,以前的对象的保留计数将回落到1。但它不会达到0

有三种解决方案:

// OK 
self.rate = [[[NSMutableDictionary alloc] init] autorelease]; 

// Better, has the same effect as statement above 
self.rate = [NSMutableDictionary dictionary]; 

// Clumsy, but works 
NSMutableDictionary *tmp = [[NSMutableDictionary alloc] init]; 
self.rate = tmp; 
[tmp release]; 

记住,每次你打电话alloc/initcopy,你会得到一个你拥有的物体。这意味着您立即负责调用release。几乎所有其他方法都会/应该返回一个对象,您不需要调用release,除非您调用retained来“声明所有权”。

+0

谢谢你的回答。在dealloc中我没有任何意义:[rate release];? – user423975 2010-08-18 13:05:42

+0

在你的dealloc方法中有'[rate release]'或'self.rate = nil'(它有相同的效果)是正确的(也是必须的)。但是,你在帖子中提出的问题是,“rate”的保留数量也会太多,因为“init”没有相应的“释放”。请记住,'self.rate = ...'会增加保留计数。所以,当你的dealloc被调用的时候,“rate”变量的保留计数是2.看到这个很好的解释:http://stackoverflow.com/questions/6578/understanding-reference-counting-with-cocoa- Objective-C的 – DarkDust 2010-08-18 14:18:24