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 に答える