I am using the FMDatabase SQLite wrapper in Objective C and I have the following issue:
I am running an XML parse and DB insert in a background thread for some content that the user does not have access to, however the user is able to interact with a UI and database from the section they are in.
The FMDatabase <FMDatabase: 0x17b7b0> is currently in use.
Randomly, I will get a "FMDatabase already in use" notification and the array will never be populated by the database. I was under the impression that the FMDatabase class would handle the query once it became free, but I have a:
while(contents.count < 1){
sleep(1);
}
Hoping that once the database frees up, the array will be populated. I have also tried rerunning the array population script if the DB is busy but to no avail.
Sorry if this question is confusing, I am happy to clarify.
I experienced the same issue.
I switched to FMDatabaseQueue
for every database query/update I had to do. It works like a charm !
Using performSelectorOnMainThread
is a good idea but when it comes to actual coding it can be pretty tricky to pass your arguments and get the results for further use.
EDIT : here is a little example
-(void) updateTaskStateAsync:(NSNumber *)taskID withNewStatus:(NSNumber *)state andCompletionBlock:(void(^)(BOOL status))completionBlock{
NSString *errInfo = [NSString stringWithFormat:@"taskID %d - state %d", [taskID intValue], [state intValue]];
[queue inDatabase:^(FMDatabase *db) {
BOOL r = [db executeUpdate:@"UPDATE tasks SET state=?, date_job_last_updated=? WHERE identifier=?", state, [NSDate dateWithTimeIntervalSinceNow:0], taskID];
DB_DISPLAY_ERROR(errInfo); // convenient macro to log errors
if(completionBlock)
completionBlock(r);
}];
}
-(BOOL) updateTaskStateSync:(NSNumber *)taskID withNewStatus:(NSNumber *)state {
NSString *errInfo = [NSString stringWithFormat:@"taskID %d - state %d", [taskID intValue], [state intValue]];
__block BOOL r = NO;
__block BOOL ended = NO;
[queue inDatabase:^(FMDatabase *db) {
r = [db executeUpdate:@"UPDATE tasks SET state=?, date_job_last_updated=? WHERE identifier=?", state, [NSDate dateWithTimeIntervalSinceNow:0], taskID];
DB_DISPLAY_ERROR(errInfo); // convenient macro to log errors
ended = YES;
}];
NSCondition *cond = [[NSCondition alloc] init];
[cond lock];
while(!ended)
[cond wait];
[cond unlock];
return r;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With