1

iOSアプリで最も奇妙な動作を見つけました。私はこのコードを持っています:

         dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
             CMLog(@"Start Save RoundQuestions Asynchronously");
             [round saveRoundQuestions:target selector:selector];
         });

その関数は作業を終了し、これを呼び出します。

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
        [target performSelector:selector];
#pragma clang diagnostic pop

ログにはすべてが正しく実行されていることが示されていますが、ターゲットはnavigationControllerでpushViewControllerを呼び出しており、実際のプッシュを実行するには永遠に時間がかかります。ホームボタンをクリックすると、強制的に続行できます。スレッドセーフに違反している可能性があり、実行ループをスリープ解除する必要がある可能性があることを読みました。

dispatch_asyncからセレクターを呼び出すのは間違っていますか?または、UIがあるメインスレッドでセレクターを実行する必要がありますか?

編集:私は実際に問題を理解しました。私は、saveRoundQuestions内のUIをブロックしている関数を呼び出していたことがわかりました。これは、いわば、プッシュアニメーションを行の後ろに強制していると思います。この関数をバックグラウンドに置くと、プッシュアニメーションがすぐに実行されます。しかし、私はまだ理由について興味がありますか?

4

2 に答える 2

4

メインスレッドでのみUIの更新を行う必要があるため、以下を使用してメインキューを取得する必要があります。

dispatch_get_main_queue()

それ以外のdispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)

私の答えはまだ残っています、dispatch_get_global_queuewoudがメインスレッドのキューを返すという保証はありません、それはただの優先度の高いキューです

名前: dispatch_get_global_queue
要約:指定された優先度レベルの既知のグローバル並行キューを返します。

于 2012-04-13T13:31:12.063 に答える
1

dispatch_asyncを使用してUIを正常に更新できます。dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)使用する代わりにdispatch get_main_queue()

編集:あなたの更新によると。内部で高価な仕事をsaveRoundQuestionsしてからupdateUIを実行している場合は、次を使用する必要があります。

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
         CMLog(@"Start Save RoundQuestions Asynchronously");
         [round saveRoundQuestions:target selector:selector];
     });

そして、UIを更新するためsaveRoundQuestionsに別のブロックを中に入れます。dispatch_get_main_queue()

于 2012-04-13T13:33:02.687 に答える