0

如果 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    
});

会引发 BAD_EXEC。

那么如何让这段代码线程安全呢?

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

dispatch_apply(count, dispatch_get_main_queue(), ^(size_t i) 
{
   /// my sqllite queries
});

但我对此并不满意。如何让它变得更好?

4

2 回答 2

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
});

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

FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];

[queue inDatabase:^(FMDatabase *db) {

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

}];

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

还不相信?

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

现在怎么样?

此外,自定义的基于块的 SQLite 函数

于 2012-12-15T01:23:32.350 回答
0
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

});
于 2014-05-12T05:08:56.287 回答