0

私の「viewWillAppear」コールバックでは、UITableViewController に SQLite データベースからのデータを入力して、ユーザーが表示できるようにします。

ただし、別のタブに切り替えて新しいデータ行を SQLite にコミットし、UITableViewController に戻すと、データベースに追加したばかりの新しい行で更新されないことに気付きました。テーブル ビューに新しい行が反映されていることを確認するには、アプリを完全に終了して UITableViewController に戻る必要があります。

この問題を回避するにはどうすればよいですか (つまり、何回も切り替えた後、UITableViewController の SQLite で常に最新の情報を強制的に表示するにはどうすればよいですか?)

すべて/アドバイスをいただければ幸いです。

コードは次のとおりです。

- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSLog(@"viewwillappear");
//[[self tableView] reloadData];
int rc=-1;
if (databasePath == nil) {
    NSLog(@"database path is NIL. Trying to set it");
    databaseName = @"mymemories.sqlite";
    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDir = [documentPaths objectAtIndex:0];
    databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
    return;
}
rc = sqlite3_open([databasePath UTF8String], &database);
if(rc == SQLITE_OK) {
    memoriesArray = [[NSMutableArray alloc]init ];
    sqlite3_stmt *statement = nil;


    NSString *fullQuery = @"SELECT * FROM memories";

    const char *sql = [fullQuery UTF8String];

    if(sqlite3_prepare_v2(database, sql, -1, &statement, NULL)!=SQLITE_OK)
        NSAssert1(0, @"Error preparing statement '%s'", sqlite3_errmsg(database));
    else
    {
        while(sqlite3_step(statement) == SQLITE_ROW)
        {
            NSString *place= [NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 4)];
            //[User setName:[NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 1)]];
            //[User setAge:[NSString stringWithUTF8String:(const char*)sqlite3_column_text(statement, 2)]];

            [memoriesArray addObject:place];
            //[currentUser release];
        }
    }
    sqlite3_finalize(statement);
    sqlite3_close(database);
}

}

また、これが関連する場合に備えて、SQLite データベースにコミットするコードを次に示します。

    NSData * blob = [NSData dataWithContentsOfURL:recordedTmpFile];
int rc=-1;
rc = sqlite3_open([databasePath UTF8String], &database);

if(rc == SQLITE_OK) {
    sqlite3_exec(database, "BEGIN", 0, 0, 0);


    NSLog(@"Connected To: %@",databasePath);
    sqlite3_stmt *updStmt =nil; 
    const char *sql = "INSERT INTO memories (data,place) VALUES (?,?);";

    rc = sqlite3_prepare_v2(database, sql, -1, &updStmt, NULL);

    if(rc!= SQLITE_OK)
    {
        NSLog(@"Error while creating update statement:%@", sqlite3_errmsg(database));
    }
    sqlite3_bind_text( updStmt, 2, [[tags text] UTF8String], -1, SQLITE_TRANSIENT);
    rc = sqlite3_bind_blob(updStmt, 1, [blob bytes], [blob length] , SQLITE_BLOB);

    if((rc = sqlite3_step(updStmt)) != SQLITE_DONE)
    {
        NSLog(@"Error while updating: %@", sqlite3_errmsg(database));
        sqlite3_reset(updStmt);
    } 

    sqlite3_exec(database, "COMMIT", 0, 0, 0);
    //rc = sqlite3_reset(updStmt);

    sqlite3_close(database);

}
4

2 に答える 2

1

ダレンの答えの説明の延長として。

まず、彼の答えは正しいです。次に、一貫性を確保するために NSMutableArray を使用する必要があります。これは、必要に応じて更新しないことで問題が発生する場所です。

一貫性を確保するために実行する必要がある手順は次のとおりです。

テーブルへのデータのロード

  • viewDidLoad で、SQL ステートメントを呼び出して配列にロードします。
  • viewWillAppear で、配列にデータが含まれていることを確認します。そうでない場合は、結果が返されなかったという通知を表示します

データベースへのデータの保存

NSMArray を使用して更新とアプリの読み込みの間の一貫性を確保することは、数十年の経験を持つ同僚によって過去に推奨されたかなり一般的な方法です。

注: データソースを同期して、常に 1 つのスレッドがアクセスしていることを確認する必要があります。そうしないと、クラッシュが発生します。

于 2012-05-24T23:47:06.447 に答える
1

SQL データを配列に読み取り、この配列を使用して UITableView を構築すると仮定すると、SQL データベースにレコードを追加するときに、テーブルの構築に使用した配列にも追加するか、または再読み込みする必要があります。データベースから配列へのデータ。

于 2012-05-24T21:15:42.963 に答える