iOS - 对象发送自动释放次数太多

时间:2012-02-19 13:22:36

标签: objective-c memory-management ios4

我有一个方法是从sqlite数据库中读取一些信息并初始化一个名为Achievement的类。当我分析这段代码时,我得到了反馈'对象发送自动释放太多次'。我真的不明白我哪里出错了 - 为什么retval对象在225行发布而不是在229行的return语句中?

有人可以在下面的代码中解释我在哪里犯了错误以及如何解决它?

功能代码(因此回答者可以轻松复制/粘贴):

- (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 个答案:

答案 0 :(得分: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];

答案 1 :(得分:1)

我猜你的编译器与allocinitautorelease的错误序列混淆了。您应该做的是以下(伪代码):

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