2010-08-18 48 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