自定义对象的分析器和自动释放问题

时间:2013-01-29 10:29:48

标签: ios objective-c sqlite

我有一个管理项目数据库查询的类,我在内存管理和代码的[return autorelease]部分遇到了一些问题。我不知道如何将对象返回给调用函数,但之后它会使用它。 代码是这样的:

-(Hexagram *)getHexagramforId:(NSInteger)hexagramNumber{
    Hexagram *current;
    if (init_statement == nil) {
        const char * sql = "SELECT * FROM HEXNUMBER where _id =?";
    if (sqlite3_prepare_v2(database, sql, -1, &init_statement, NULL) != SQLITE_OK) {
        NSAssert1(0, @"Error:failed to prepare argument with message %s", sqlite3_errmsg(database));
    }
    sqlite3_bind_int(init_statement, 1, hexagramNumber);
    if (sqlite3_step(init_statement) == SQLITE_ROW) {
        current = [[Hexagram alloc]initWithId:hexagramNumber
                                             Title:[NSString stringWithUTF8String:(char*)sqlite3_column_text(init_statement, HEX_TITLE)]
                                               LongText:[NSString stringWithUTF8String:(char*)sqlite3_column_text(init_statement, HEX_TEXT)]ShortText:nil InternalColor:sqlite3_column_int(init_statement, INTERNAL_COLOR) ExternalColor:sqlite3_column_int(init_statement, EXTERNAL_COLOR)];

    }else{
        NSAssert1(0, @"Database is corrupt, error %s", sqlite3_errmsg(database));
    }
    sqlite3_reset(init_statement);
    sqlite3_close(database);
    init_statement = nil;
    return current;
}
return nil;

}

所以会发生的事情是在分析器中它说对象当前的六芒星是泄漏的,但是如果我用自动释放它返回它会崩溃。我想支持iOS< 5所以我不想使用ARC但到目前为止我不知道如何返回此对象并且不会在静态分析器中出现此错误。有什么帮助吗?

1 个答案:

答案 0 :(得分:0)

首先,分析师抱怨的原因是因为您通过Hexagram创建了alloc] init对象,并将其返回,这意味着您的对象将以保留计数开始1.除非您的方法名称以new / alloc / copy开头,否则代码(和静态分析器)的用户将期待一个自动释放的对象。 (见documentation of naming conventions + memory management)。

至于自动释放; Autorelease将为对象提供1的保留计数(以便它可以暂停一段时间),但会在运行循环结束时释放。这将导致保留计数为0,并且对象将被取消分配。

现在,为什么return [current autorelease]会失败?原因是因为方法getHexagramforId的调用者。如果有人正在调用一个方法来返回一个自动释放的对象(一个不以new / alloc / copy等开头的方法......),那么是他们的责任来保持该对象的时候它需要(出于上述原因)。

例如,如果您将return current更改为return [current autorelease],并将方法调用为:

Hexagram* obj = [[SomeClass getHexagramforId:3] retain];

你的程序不应该崩溃。您明确保留了一个自动释放的对象,因此您现在可以保留该对象,直到您不再需要它为止。此时,请致电[obj release]

保留自动释放对象的其他方法包括将其分配给保留属性,如下所示:

@property (nonatomic, retain) Hexagram* hexObj;

self.hexObj = [SomeClass getHexagramForId:3];