0

我有一个包含学生实体的数据库:

create table student ( name varchar(20) not null,
                       surname varchar(20) not null,
                       studentId integer primary key );

在我的应用程序委托中,当应用程序启动时,我从数据库中加载所有元组并将它们显示到表视图中。
当应用程序委托接收 applicationWillResignActive 事件时,它将所有元组保存到数据库中。它只保存已添加的元组,不可能编辑元组,所以没关系。
当应用程序委托接收到 applicationWillEnterForeground 事件时,它会从数据库中读取元组。

问题:这只适用于应用程序的单次启动。假设我通过 Xcode 启动应用程序,然后输入我添加一个元素并在后台输入。之后我重新激活应用程序,它进入前台并加载成功的所有元组。
但是在应用程序的下一次启动(从 lldb 停止它并再次启动它)时,元组与第一次启动之前相同。

我为学生实体创建了一个包装类,名为 Student,具有以下属性:

@property (nonatomic, copy, readwrite) NSString* name;
@property (nonatomic, copy , readwrite) NSString* surname;
@property (nonatomic, strong, readwrite) NSNumber* studentId;
@property (nonatomic, readwrite, getter= isNew) BOOL new;

我检查这些字段不为零,并且不违反实体完整性。
我使用的唯一有意义的方法是:

- (NSString*) sqlInsertionString;

它创建插入元组所需的字符串。测试并工作。

这就是我更新数据库的方式:

- (void) updateStudents : (NSMutableArray*) students
{
    sqlite3* database;
    sqlite3_stmt* statement;
    BOOL needsFinalize=NO;
    if(!databasePath)
    {
        NSBundle* bundle=[NSBundle mainBundle];
        databasePath= [bundle pathForResource: @"test" ofType: @"db"];
    }
    if(sqlite3_open([databasePath UTF8String], &database)!=SQLITE_OK)
    {
        NSString* problem= [NSString stringWithFormat: @"%s",sqlite3_errmsg(database)];
        @throw [NSException exceptionWithName: @"Failed to open the database" reason: problem userInfo: nil];
    }
    for(Student * s in students)
    {
        if(s.isNew)
        {
            NSString* sqlString= [s sqlInsertionString];
            if(sqlite3_prepare_v2(database, [sqlString UTF8String], -1, &statement, NULL)!= SQLITE_OK)
            {
                @throw [NSException exceptionWithName: @"Problem performing the query" reason: @"Unknown" userInfo: nil];
            }
            if(sqlite3_step(statement)!=SQLITE_DONE)
            {
                @throw [NSException exceptionWithName: @"Problem performing the query" reason: @"Unknown" userInfo:nil];
            }
            sqlite3_reset(statement);
            needsFinalize=YES;
        }
    }
    if(needsFinalize && sqlite3_finalize(statement)!=SQLITE_OK)
    {
        @throw [NSException exceptionWithName: @"Failed to close the statement resource" reason: @"Unknown" userInfo:nil];
    }
    if(sqlite3_close(database)!= SQLITE_OK)
    {
        @throw [NSException exceptionWithName: @"Failed to close the database" reason: @"Unknown" userInfo: nil];
    }
}

但它并没有真正更新,只是在应用程序内部它似乎已更新,但文件始终保持不变。

4

1 回答 1

2

问题是您正在从捆绑包中打开数据库。您不能对此进行(持久)修改。标准的解决方案是检查Documents文件夹中的数据库,如果有,使用它,如果没有,从 bundle 复制到Documents然后从Documents.

请参阅无法在 iOS 中连接 SQLite 数据库

于 2012-12-13T16:53:00.223 回答