2012-02-19 33 views
0

我有一個方法是從sqlite數據庫中讀取一些信息並初始化一個名爲Achievement的類。當我分析這段代碼時,我得到的反饋是「對象多次發送autorelease」。我真的不明白我的錯在哪裏 - 爲什麼retval對象在第225行釋放,而不是第229行的return語句?iOS - 對象發送autorelease太多次

有人可以解釋我在下面的代碼中犯了什麼錯誤,以及我如何解決它?

功能代碼(這樣回答者可以輕鬆地複製/粘貼):

- (Achievement *)getAchievement:(int)Id 

{

Achievement *retval = [[Achievement alloc] autorelease]; 

NSString *query = [NSString stringWithFormat:@"SELECT * FROM Achievements where ID = %d", Id]; 

sqlite3_stmt *statement; 

if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &statement, nil) 
    == SQLITE_OK) { 
    while (sqlite3_step(statement) == SQLITE_ROW) { 
     int Id = sqlite3_column_int(statement, 0); 
     char *name = (char *) sqlite3_column_text(statement, 1); 
     char *title = (char *) sqlite3_column_text(statement, 2); 
     char *description = (char *) sqlite3_column_text(statement, 3); 

     Boolean Achieved; 
     char *com = (char *) sqlite3_column_text(statement, 4); 
     NSString *c1 = [[[NSString alloc] initWithUTF8String:com] autorelease]; 
     Achieved = [c1 isEqualToString:@"1"]; 

     NSDate *CompletedDate = (NSDate *) sqlite3_column_text(statement, 5); 

     char *icon = (char *) sqlite3_column_text(statement, 6); 

     int New = sqlite3_column_int(statement, 7); 

     NSString *Title = [[[NSString alloc] initWithUTF8String:title] autorelease]; 
     NSString *Description = [[[NSString alloc] initWithUTF8String:description] autorelease]; 
     NSString *Name = [[[NSString alloc] initWithUTF8String:name] autorelease]; 
     NSString *Icon = [[[NSString alloc] initWithUTF8String:icon] autorelease]; 

     retval = [retval initDetails:Id :Name :Title: Description : Achieved : CompletedDate: Icon: New]; 
    } 
    sqlite3_finalize(statement); 
} 
return retval; 

}

分析反饋的圖像: enter image description here

一如往常的任何反饋非常感謝。

回答

2
Achievement *retval = [[Achievement alloc] autorelease]; 

這是非常糟糕的主意,要做到這一點。在使用它之前,你總是必須初始化對象。 相反,你要初始化它在一個循環:

retval = [retval initDetails:Id :Name :Title: Description : Achieved : CompletedDate: Icon: New]; 

我真的不明白爲什麼你需要對同一個對象多次初始化。也許,你需要創建多個對象並用不同的值初始化它們?

重新排列如下:

Achievement *retval = nil; 
while (...) { 
    [retval release]; 
    retval = [[Achievement alloc] initDetails: ...]; 
} 
return [retval autorelease]; 
+0

感謝Max,while只會被迭代一次(SQL將只返回一行)。我在循環中初始化它,因爲從db調用返回的值在那裏可用。你如何建議我重新安排功能? – MattStacey 2012-02-19 13:46:05

1

我想你混淆了的allocinitautorelease順序錯誤的編譯器。你應該做的是下面的代碼(僞代碼):

Achievement *retval = nil; 
while (...) { 
    retval = [[[Achievement alloc] initDetails: ...] autorelease]; 
} 
return retval; 
+0

啊,一分錢一滴。謝謝。 – MattStacey 2012-02-19 13:54:27