0

在我的“viewWillAppear”回调中,我尝试使用 SQLite 数据库中的数据填充 UITableViewController 以供用户查看。

但是,我注意到如果我切换到另一个选项卡,将新的数据行提交到 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

假设您将 SQL 数据读入一个数组,然后使用该数组构建 UITableView,当您向 SQL 数据库添加一条记录时,您要么需要将它也添加到用于构建表的数组中,要么重新读取将数据库中的数据存入数组。

于 2012-05-24T21:15:42.963 回答
1

作为对达伦答案的解释的延伸。

首先他的回答是正确的。其次,您需要使用 NSMutableArray 来确保一致性,这是您出错的地方,因为您不应该更新它

为确保一致性而应采取的步骤如下:

将数据加载到表中

  • 在 viewDidLoad 中,调用您的 SQL 语句并将其加载到您的数组中
  • 在 viewWillAppear 中确保您的数组包含数据,如果不显示没有返回结果的通知

将数据保存到数据库

  • 更新对数组(或数据源)的更改
  • 使用更新的数据源更新数据库以确保一致性
  • 使用 4 种 UITableView 重新加载方法之一更新表格

过去,拥有数十年经验的同事向我推荐使用 NSMArray 来确保更新和应用程序加载之间的一致性是相当普遍的做法。

注意:您需要同步数据源以确保 1 个线程在任何时候都在访问它,否则您将遇到崩溃。

于 2012-05-24T23:47:06.447 回答