I\'m using an SQLite database in my iPhone app. At startup, there are some database actions that I want to perform in a separate thread. (I\'m doing this mainly to minimize
SQLite handles (sqlite3_stmt *
for sure, and sqlite3 *
I think) are thread-specific. The correct way to call them from multiple threads is to maintain a separate set of handles for each thread.
I would use NSOperation and just do everything there during startup. NSOperation rocks. Did I say how much NSOperation rocks? It does. Rock, that is.
If you are still not having any luck with above, you could try using this wrapper by EnormEGO https://github.com/jdp-global/egodatabase
They use asynchronous callbacks which may kill two birds with one stone.
Have a look at my Readme section for EGODatabaseRequest - asynchronous requests to db
If you want to use SQLite on multiple threads with no restrictions, do the following before opening your connection:
sqlite3_shutdown();
sqlite3_config(SQLITE_CONFIG_SERIALIZED);
sqlite3_initialize();
http://www.sqlite.org/threadsafe.html
My solution is to delete the app on my device (I want to delete the database that I created). This solves the problem for me.
I've tried these two solutions and they worked perfectly. You can either use critical sections or NSOperationQueue and I prefer the first one, here is the code for both of them:
define some class "DatabaseController" and add this code to its implementation:
static NSString * DatabaseLock = nil;
+ (void)initialize {
[super initialize];
DatabaseLock = [[NSString alloc] initWithString:@"Database-Lock"];
}
+ (NSString *)databaseLock {
return DatabaseLock;
}
- (void)writeToDatabase1 {
@synchronized ([DatabaseController databaseLock]) {
// Code that writes to an sqlite3 database goes here...
}
}
- (void)writeToDatabase2 {
@synchronized ([DatabaseController databaseLock]) {
// Code that writes to an sqlite3 database goes here...
}
}
OR to use the NSOperationQueue you can use:
static NSOperationQueue * DatabaseQueue = nil;
+ (void)initialize {
[super initialize];
DatabaseQueue = [[NSOperationQueue alloc] init];
[DatabaseQueue setMaxConcurrentOperationCount:1];
}
+ (NSOperationQueue *)databaseQueue {
return DatabaseQueue;
}
- (void)writeToDatabase {
NSInvocationOperation * operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(FUNCTION_THAT_WRITES_TO_DATABASE) object:nil];
[operation setQueuePriority:NSOperationQueuePriorityHigh];
[[DatabaseController databaseQueue] addOperations:[NSArray arrayWithObject:operation] waitUntilFinished:YES];
[operation release];
}
these two solutions block the current thread until the writing to database is finished which you may consider in most of the cases.