簡體   English   中英

我不太了解的新手泄漏

[英]Newbie leaks that I don't quite understand

修復了Instruments指示的其他漏洞之后,我發現自己需要幫助,可以通過以下代碼找到我的泄漏:

-(void)readHistoryFromDatabase {sqlite3 * database;

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 * rate;

並在viewDidLoad中:

self.rate = [[NSMutableDictionary alloc] init];

基本上,這部分代碼從數據庫中讀取一些速率。 根據月份,它將在NSDictionary中放入兩個月和一個包含費率的數組。

我不知道泄漏在哪里。 我知道這也許很簡單,但我現在正在尋找2天的解決方案.....

[[NSMutableDictionary alloc] init]返回保留計數為1的對象。然后將其分配給self.rate ,這會增加保留計數(然后為2)。 如果您為self.rate分配其他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以“聲明所有權”。

在儀器中,您可以查看泄漏的來源,按擴展的詳細信息按鈕並選擇泄漏,然后您將看到泄漏的來源,方法和文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM