2012-02-19 2 views
0

sqlite db에서 일부 정보를 읽고 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

감사합니다. 최대는 한 번만 반복됩니다 (SQL은 한 행만 반환합니다). db 호출에서 반환 된 값을 사용할 수 있기 때문에 루프에서 초기화합니다. 어떻게 기능을 재 배열 할 것을 제안합니까? – MattStacey

1

난 당신이 alloc, init, autorelease의 잘못된 순서로 컴파일러를 혼란 것 같아요. 대신에해야 할 일은 다음과 같습니다 (의사 코드).

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

아, 페니 드롭 순간. 감사. – MattStacey

관련 문제