私はFMDBを使用して、正常に機能するデータベースを処理しています。アプリは、いくつかの作業を行っており、データベースにアクセスする必要があるバックグラウンドスレッドを使用します。同時に、メインスレッドは同じデータベースでいくつかのクエリを実行する必要があります。FMDB自体には小さなロックシステムがありますが、クラスにもう1つ追加しました。
すべてのクエリは、私のクラスがデータベースが使用されていないことを示している場合にのみ実行されます。アクションを実行した後、データベースのロックが解除されます。これは、負荷が高すぎない限り、期待どおりに機能します。メインスレッドで実行されているスレッドで大量のデータにアクセスすると、EXC_BAD_ACCESSエラーが発生します。
これが見た目です:
- (BOOL)isDatabaseLocked {
return isDatabaseLocked;
}
- (Pile *)lockDatabase {
isDatabaseLocked = YES;
return self;
}
- (FMDatabase *)lockedDatabase {
@synchronized(self) {
while ([self isDatabaseLocked]) {
usleep(20);
//NSLog(@"Waiting until database gets unlocked...");
}
isDatabaseLocked = YES;
return self.database;
}
}
- (Pile *)unlockDatabase {
isDatabaseLocked = NO;
return self;
}
デバッガーは、エラーが[FMResultSet next]
行で発生すると言います
rc = sqlite3_step(statement.statement);
すべての保持カウントを再確認しましたが、現時点ではすべてのオブジェクトが存在します。繰り返しになりますが、これは、バックグラウンドスレッドの実行中にメインスレッドが多くのクエリを開始した場合にのみ発生します(それ自体が常に重い負荷を生成します)。エラーは常にメインスレッドによって生成され、バックグラウンドスレッドによって生成されることはありません。
私の最後のアイデアは、両方のスレッドがlockedDatabaseを同時に実行して、データベースオブジェクトを取得できるようにすることです。そのため、「@ synchronized(self)」を介してミューテックスロックを追加しました。しかし、これは役に立ちませんでした。
誰か手がかりがありますか?