私はiPad用のアプリを開発していて、sqliteセンテンス(選択、更新、挿入、削除)を使用しています。
各文の最初でデータベースを開き(sqlite3_open)、最後で閉じます(sqlite3_close)。しかし、「データベースがロックされています」というメッセージが表示されることがあります。
これを解決するために何ができるかわかりません。
この小さな情報に感謝し、申し訳ありません。
私が間違っていなければ、sqllite の問題は、一度に 1 回しかアクセスできないことです。複数のスレッドがある場合は、この状況で実行できます。例:
スレッド t1 で method1 (データベースにアクセスする) を実行します。x 秒後にスレッド t2 で (データベースにアクセスする) method2 を実行します。
method1 が x 秒以内に終了しない場合、両方のメソッドが同時にアクセスします。そして、私が言ったように、私は sqllite がこれをサポートしていないことを知っています。
データベースの使用状況にフラグを立てる必要があります。アクセスしたいが使用中の場合は、x 秒後にもう一度試してください。このような:
- (void) generalMethodThatUsesDatabses
{
if(databaseIsUsed)
{
[self performSelector:@selector(generalMethodThatUsesDatabses) withObject:nil afterDelay:5];
return;
}
databaseIsUsed = TRUE; //global bool variable
//your code here
databaseIsUsed = FALSE;
}
お役に立てれば。乾杯!
これを解決する良い方法は、これを C++ ライブラリにラップすることです。このようにして、スタック上にライブラリ ラッパーを作成できます。これは、関数が範囲外になった瞬間に、デストラクタで接続を閉じることができることを意味します。
(Objective-C では参照カウントを使用していることに注意してください)
例えば:
NSArray* ScoreBoard::getAllScores()
{
ScoreBoard::ensureExistingTable();
//Stack allocated
SqliteWrapper sqlite("Scores.sqlite");
NSArray* result = sqlite.RunQuery("SELECT * FROM Scores ORDER BY ID DESC");
return result;
//after this, the sqlite destructor is called
}
Objective-C コンパイラで C++ をマージできるのは非常に便利です。非常に便利です。
また
void SqliteWrapper::Close()
{
sqlite3_close(db);
}
Vincent が指摘したように、ステートメントを完成させる必要があります。接続を開いたままにしたい場合は、各ステートメントの後に finalize を使用します。接続を破棄する瞬間に接続を閉じます。
この方法は私にとってはうまくいきます。