Reputation: 16301
If libsqlite is not thread safe a code like that
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
__block NSArray *__albumsCollection = albumCollections;
dispatch_apply(count, queue, ^(size_t i)
{
MPMediaItem *albumObj = [[__albumsCollection objectAtIndex:i] representativeItem];
///// making some sqlite queries
});
would raise a BAD_EXEC.
So how to make this code thread safe?
My solution was using the main queue
dispatch_apply(count, dispatch_get_main_queue(), ^(size_t i)
{
/// my sqllite queries
});
but I'm not satisfied with that. How to make it better?
Upvotes: 0
Views: 2159
Reputation: 441
dispatch_queue_t q=dispatch_queue_create("name", NULL);
dispatch_sync(q, ^{
//your code is here
});
dispatch_async(dispatch_get_main_queue(), ^(void) {
//as soon as above block is completed, this block executed and you will be notified that
//work is completed
});
Upvotes: 0
Reputation: 29552
Instead of using dispatch_get_main_queue()
to get the main queue you might want to create a separate private dispatch queue on a non-main thread like so:
dispatch_queue_t queue = dispatch_queue_create("com.example.MyQueue", DISPATCH_QUEUE_SERIAL); // or NULL as last parameter if prior to OS X 10.7/iOS 5.0
dispatch_apply(count, queue, ^(size_t i) {
/// your SQLite queries
});
Alternatively you could use a FMDatabaseQueue
from Gus Mueller's (@ccgus) brilliant FMDB SQLite wrapper framework (which is what I'd do):
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];
[queue inDatabase:^(FMDatabase *db) {
// Your SQLite queries:
[db executeQuery:@"...", ...];
...
}];
…which will send your query block to a serial dispatch queue, wrapping its execution synchronously.
Not convinced yet?
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
// Your SQLite queries:
[db executeQuery:@"...", ...];
...
}];
How about now?
Also, custom-defined block-based SQLite functions.
Upvotes: 5