在主调度队列上显示UI元素会导致元素出现然后消失

Dev*_*Fly 3 cocoa-touch objective-c grand-central-dispatch

我想在开始长任务之前显示进度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];
    });
}
Run Code Online (Sandbox Code Playgroud)

SVProgressHUD用于进步HUD.我打电话的方法addProcess使用dispatch_async()

如果我使用旧的+[NSThread detach...],它可以完美地工作,但我不想再使用它了.

Rob*_*Rob 8

有几件事:

  1. 关键的观察是dispatch_async除非你需要,否则总是使用dispatch_sync.您不需要在此处进行同步操作,因此只需使用dispatch_asyncUI更新即可.

  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];
        });
    });
}
Run Code Online (Sandbox Code Playgroud)

或者,或者,

- (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];
        });
    });
}
Run Code Online (Sandbox Code Playgroud)

如果你正在......

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [self addProcess]; 
});
Run Code Online (Sandbox Code Playgroud)

那就是:

- (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];
    });
}
Run Code Online (Sandbox Code Playgroud)