libsqlite和dispatch_async

lor*_*isi 0 sqlite objective-c thread-safety grand-central-dispatch

如果libsqlite不是线程安全的,则类似这样的代码

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    
});
Run Code Online (Sandbox Code Playgroud)

会引发一个BAD_EXEC。

那么如何使此代码线程安全?

我的解决方案是使用主队列

dispatch_apply(count, dispatch_get_main_queue(), ^(size_t i) 
{
   /// my sqllite queries
});
Run Code Online (Sandbox Code Playgroud)

但我对此不满意。如何使它更好?

Reg*_*ent 5

dispatch_get_main_queue()您可能想要在非主线程上创建一个单独的私有调度队列,而不是用来获取主队列,如下所示:

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
});
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用FMDatabaseQueueGus Mueller(@ccgus)出色的FMDB SQLite包装器框架(这是我要做的):

FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];

[queue inDatabase:^(FMDatabase *db) {

    // Your SQLite queries:
    [db executeQuery:@"...", ...];
    ...

}];
Run Code Online (Sandbox Code Playgroud)

…这会将您的查询块发送到串行调度队列,并同步包装其执行。

还没说服?

[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
    // Your SQLite queries:
    [db executeQuery:@"...", ...];
    ...
}];
Run Code Online (Sandbox Code Playgroud)

现在怎么样?

还有,自定义基于块的SQLite函数