2

これがどのように機能するかについて、いくつかの基本的な誤解があると思います。助けていただければ幸いです。私はsqliteテーブルからデータをプルし、それをオブジェクトに入れ、そのオブジェクトを配列に保存するいくつかの関数を書き込もうとしてきました。その後、その配列は他のルーチンによってアクセスされます。このクラスには、フォーラムを詰まらせたくないものがたくさんあります。私がこれを抱えている問題は次のとおりです。

1)配列に入れられた最終値にしかアクセスできないようです。'User'オブジェクトを誤って配列に保存していますか?

2)配列内のオブジェクトを正しく取得したと仮定して、オブジェクトを正しく引き出していますか?下部にサンプルプルルーチンを追加しました。

3)経験が豊富な人は、これを行うためのより効率的な方法について言及できますか?私はまだxcodeプログラミングの足を引っ張ろうとしています。よりクリーンなコードを書くための提案をいただければ幸いです。

//**SQLiteFunctionsヘッダー

#import <sqlite3.h>
#import "Users.h"

@interface SQLiteFunctions : NSObject
{
@public
    // initializing public variables
    NSMutableArray *returnData;

@private
    // initializing private variables
    sqlite3 *dbPointer;
    sqlite3_stmt *sqlStatement;
    NSArray *paths;
    NSString *documentsDirectory;
    NSString *databasePath;
    char *error;
    Users *users;
}

// initializing public member functions
-(BOOL)openDatabase: (NSString *) table_name;
-(BOOL)openBundleDatabase;
-(BOOL)openNonBundleDatabase;
-(void)closeDatabase;
-(BOOL)getRecords:(const char *)sqlquery;
-(int)getUserRecords:(const char *)sqlquery;

@end

//**SQLiteFunctionsの実装

-(int)getUserRecords:(const char *)sqlquery
{
    // retreiving database values
    users = [[Users alloc] init];

    // initializing return data array
    returnData = [[NSMutableArray alloc] init];

    // testing prepare statement for verse sql
    if(sqlite3_prepare(dbPointer, sqlquery, -1, &sqlStatement, NULL) == SQLITE_OK)
    {
        // looping through existing return rows
        while (sqlite3_step(sqlStatement)==SQLITE_ROW)
        {
            // retreiving database values
            users->user_id = sqlite3_column_int(sqlStatement,0);
            users->user_name = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement, 1)];

            // adding verse object to the return data array
            [returnData addObject:users];
        }
    }
    else
    {
        // logging problem with prepare
        NSLog(@"Problem with prepare statement:  %s", sqlite3_errmsg(dbPointer));
        return NO;
    }

    // returning number of rows in the array
    return [returnData count];
}

//**使用例

// retreiving the number of users from the database
SQLiteFunctions *sql = [[SQLiteFunctions alloc] init];
Functions *func = [[Functions alloc] init];

// testing for successful open
if([sql openDatabase:@"users"])
{
    // testing for that profile name existing already
    if([sql getUserRecords:[func strCat:@"SELECT * FROM  users;":nil:nil:nil:nil]] > 0)
    {
        int user_id;
        NSString *user_name;
        for(Users *myUser in sql->returnData)
        {
            user_id = myUser.user_id;
            user_name = myUser.user_name;
            // do other stuff with values
        }
    }
}
4

1 に答える 1

1

配列へのオブジェクトの追加の問題配列の問題は、Userオブジェクトの同じインスタンスの
値を更新し続け、それを配列に何度も追加することです。

これを修正するには、users = [[Users alloc] init];行をforループ内に移動します。

配列内
のオブジェクトへのアクセスすべて(または少なくとも多数)のオブジェクトを調べる必要がある場合は、配列内のオブジェクトにアクセスすることは問題ありません。特定のオブジェクトのみが必要な場合は、次を使用できます。

Users *user5 = [sql->returnData objectAtIndex:5];

ただし、より大きな問題は、自分のクラスの外部からivarにアクセスするべきではないということです。public ivar(returnData)を使用する代わりに、宣言されたプロパティを作成する必要があります。

まず、ivar宣言行(NSMutableArray *returnData;)を削除してから、すべてのivarを含むブロックの後にこれを追加します(// initializing public member functionsコメントのすぐ上)。

@property(nonatomic、strong)NSMutableArray * returnData;

次に、アクセサを使用してアクセスします:sql.returnDataまたは[sql returnData]の代わりにsql->returnData

于 2012-12-25T04:31:57.000 に答える