在重新启动应用程序之前,UITableViewController并不总是与实际的SQLite数据库保持一致

时间:2012-05-24 18:39:02

标签: iphone ios5 transactions sqlite

在我的“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);

}

2 个答案:

答案 0 :(得分:1)

假设您将SQL数据读入数组,然后使用此数组构建UITableView,当您向SQL数据库添加记录时,您还需要将其添加到用于构建表的数组中,或者重新 - 将数据库中的数据读入数组。

答案 1 :(得分:1)

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

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

您应采取以确保一致性的步骤如下:

将数据加载到表格

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

将数据保存到数据库

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

使用NSMArray来确保更新和应用程序加载之间的一致性是过去几十年经验丰富的同事推荐给我的。

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