3

私はiPad用のアプリを開発していて、sqliteセンテンス(選択、更新、挿入、削除)を使用しています。

各文の最初でデータベースを開き(sqlite3_open)、最後で閉じます(sqlite3_close)。しかし、「データベースがロックされています」というメッセージが表示されることがあります。

これを解決するために何ができるかわかりません。

この小さな情報に感謝し、申し訳ありません。

4

4 に答える 4

6

私が間違っていなければ、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;

}

お役に立てれば。乾杯!

于 2012-10-17T07:39:34.900 に答える
0

これを解決する良い方法は、これを 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 を使用します。接続を破棄する瞬間に接続を閉じます。

この方法は私にとってはうまくいきます。

于 2013-10-21T09:50:31.647 に答える