0

学生エンティティを持つデータベースがあります。

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

アプリケーションの起動時にアプリデリゲートで、データベースからすべてのタプルをロードし、それらをテーブルビューに表示します。
アプリデリゲートがapplicationWillResignActiveイベントを受信すると、すべてのタプルがデータベースに保存されます。追加されたタプルのみが保存されるため、タプルを編集することはできません。
アプリデリゲートは、applicationWillEnterForegroundイベントを受信すると、データベースからタプルを読み取ります。

問題:これは、アプリケーションの1回の起動内でのみ機能します。たとえば、Xcodeを介してアプリケーションを起動し、要素を追加してバックグラウンドで入力するとします。その後、アプリケーションを再アクティブ化すると、フォアグラウンドになり、ロードされます。正常にすべてのタプル。
ただし、アプリケーションの次回の起動時(lldbから停止して再度起動するとき)、タプルは最初の起動前と同じです。

次のプロパティを使用して、Studentという名前の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;

フィールドがnilでないこと、およびエンティティの整合性が侵害されていないことを確認します。
私が使用する唯一の重要な方法はこれです:

- (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フォルダー内のデータベースを確認し、存在する場合はそれを使用し、存在しない場合はバンドルからコピーしてからDocumentsデータベースを開くことDocumentsです。

iOS で SQLite データベースに接続できないを参照してください

于 2012-12-13T16:53:00.223 に答える