0

我有一个类来管理我的项目的数据库查询,我在内存管理和[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 但到目前为止我不知道如何返回这个对象并且不会在静态分析器中得到这个错误。请问有什么帮助吗?

4

1 回答 1

0

首先,分析器抱怨的原因是因为您正在Hexagram通过 创建对象alloc] init,然后像这样返回它,这意味着您的对象将以 1 的保留计数开始。除非您的方法名称以 new/alloc/copy 开头,代码(和静态分析器)的用户将期待一个自动释放的对象。(请参阅命名约定 + 内存管理的文档)。

至于自动释放;Autorelease 将给一个对象一个保留计数 1(以便它可以挂起一段时间),但将在运行循环结束时释放。这将导致保留计数为 0,并且对象被释放。

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

因此,例如,如果您更改return currentreturn [current autorelease], 并按如下方式调用该方法:

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

你的程序不应该崩溃。您正在显式保留一个自动释放的对象,因此您现在可以保留该对象,直到您不再需要它为止。此时,调用[obj release].

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

@property (nonatomic, retain) Hexagram* hexObj;

self.hexObj = [SomeClass getHexagramForId:3];
于 2013-01-29T10:47:58.623 回答