3

長いタスクを開始する直前に進行状況 HUD を表示し、タスクが完了したらそれを閉じたいです。現在、UI がしばらくフリーズし、HUD が一瞬表示されてから消えます。さらに 4 ~ 5 秒後にタスクが終了し、結果が表示されますが、進行状況 HUD は既に消えています。

- (void) addProcess:(NSString *)searchTerm
{
    dispatch_sync(dispatch_get_main_queue(), ^{
        UIApplication *app = [UIApplication sharedApplication];
        app.networkActivityIndicatorVisible = YES;
        [SVProgressHUD showWithMaskType:SVProgressHUDMaskTypeGradient];
    });

    //DO SOME VERY LONG STUFF HERE

    dispatch_sync(dispatch_get_main_queue(), ^{
        UIApplication *app = [UIApplication sharedApplication];
        app.networkActivityIndicatorVisible = NO;
        [SVProgressHUD dismiss];
    });
}

SVProgressHUD進捗HUDに使用しています。addProcessを使用してメソッドを呼び出していますdispatch_async()

古い+[NSThread detach...]ものを使えば問題なく動作しますが、もう使いたくありません。

4

1 に答える 1

8

いくつかのこと:

  1. 重要な観察事項は、dispatch_async必要な場合を除き、常に使用することですdispatch_sync。ここでは同期操作は必要ないのでdispatch_async、UI の更新に使用してください。

  2. メイン キューから実行addProcessしている場合、最初の UI 更新をメイン キューにディスパッチする必要はありません。明らかに、これをバックグラウンド キューから実行している場合は実行します。

  3. 元の質問には、 内のバックグラウンド キューへのディスパッチがありましたaddProcess。これは、私にとってより理にかなっています (すべての GCD を適切にカプセル化したままにします)。あなたはこれを経由して呼び出していると言うように回答を更新しましたdispatch_async([self addProcess])(これは、メインキューではなくグローバルキューを意味していると思います)。以下のコード サンプルでは、​​両方のシナリオに対応しています。

したがって、要するに、[self addProcess](それ自体をバックグラウンド キューにディスパッチせずに) 経由​​でこれを呼び出す場合は、次のことをお勧めします。

- (void) addProcess:(NSString *)searchTerm
{
    UIApplication *app = [UIApplication sharedApplication];
    app.networkActivityIndicatorVisible = YES;
    [SVProgressHUD showWithMaskType:SVProgressHUDMaskTypeGradient];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        //DO SOME VERY LONG STUFF HERE

        dispatch_async(dispatch_get_main_queue(), ^{
            UIApplication *app = [UIApplication sharedApplication];
            app.networkActivityIndicatorVisible = NO;
            [SVProgressHUD dismiss];
        });
    });
}

または、代わりに、

- (void) addProcess:(NSString *)searchTerm
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        dispatch_async(dispatch_get_main_queue(), ^{
            UIApplication *app = [UIApplication sharedApplication];
            app.networkActivityIndicatorVisible = YES;
            [SVProgressHUD showWithMaskType:SVProgressHUDMaskTypeGradient];
        });

        //DO SOME VERY LONG STUFF HERE

        dispatch_async(dispatch_get_main_queue(), ^{
            UIApplication *app = [UIApplication sharedApplication];
            app.networkActivityIndicatorVisible = NO;
            [SVProgressHUD dismiss];
        });
    });
}

そして、あなたがやっているなら...

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [self addProcess]; 
});

それはただです:

- (void) addProcess:(NSString *)searchTerm
{
    dispatch_async(dispatch_get_main_queue(), ^{
        UIApplication *app = [UIApplication sharedApplication];
        app.networkActivityIndicatorVisible = YES;
        [SVProgressHUD showWithMaskType:SVProgressHUDMaskTypeGradient];
    });

    //DO SOME VERY LONG STUFF HERE

    dispatch_async(dispatch_get_main_queue(), ^{
        UIApplication *app = [UIApplication sharedApplication];
        app.networkActivityIndicatorVisible = NO;
        [SVProgressHUD dismiss];
    });
}
于 2012-08-09T18:17:17.143 に答える