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

FMDatabaseQueueあるいは、Gus 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 に答える