0

データベースからロードして画面に表示する重いコンテンツがあります。しかし同時に、「データベースへの plist」保存のバックグラウンド タスクが進行中です。したがって、UI がスタックします。

私が以下のように使用しているコード、

データベースのフェッチと UI の更新メソッドの場合

- (void)performBlockInBackground:(dispatch_block_t)taskBlock
                              completion:(dispatch_block_t)completionBlock
                            withPriotity:(dispatch_queue_priority_t)piority
{
    __block dispatch_block_t taskBlockRef = taskBlock;
    __block dispatch_block_t completionBlockRef = completionBlock;

    dispatch_async(dispatch_get_global_queue(piority, 0), ^{

        dispatch_sync(dispatch_get_global_queue(piority, 0), taskBlockRef);

        dispatch_async(dispatch_get_main_queue(), completionBlockRef);
    });
}

そして、「Plist to DB」メソッドを次のように呼び出しています

[self performSelectorInBackground:@selector(syncData) withObject:nil];

これtaskBlockは重い DB フェッチでcompletionBlockあり、UI の更新です。

しばらくして(メソッドが完了した後)このメソッドを呼び出すと、syncDataスムーズに更新されます。しかし、まだ完了していない場合、UI が動かなくなります。

スレッドのデッドロックの問題のようですが、これについては明確ではありません

助けてください !!

4

1 に答える 1

3

dispatch_sync()すでに適切なキューにいる場合は必要ありません。次のようにブロックを呼び出すことができますtaskBlock()

- (void)performBlockInBackground:(dispatch_block_t)taskBlock
                    withPriority:(dispatch_queue_priority_t)priority
          completionOnMainThread:(dispatch_block_t)completionBlock
{
  dispatch_async(dispatch_get_global_queue(priority, 0), ^{
    if (taskBlock) {
      taskBlock();
    }

    if (completionBlock) {
      dispatch_async(dispatch_get_main_queue(), completionBlock);
    }
  });
}

何が起こるかは次のとおりです。

  • 作業をすぐにバックグラウンド スレッドに送信します。これで、呼び出しスレッドまたはメイン スレッドがブロックされなくなりました。
  • がある場合は、taskBlock今すぐ実行してください。TaskBlockデータフェッチを置く場所です。
  • TaskBlock終わります。
  • がある場合はcompletionBlock、それをメイン スレッドに送信します。CompletionBlockUI を更新する場所です。
于 2013-03-12T19:12:35.380 に答える