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

标签 objective-c cocoa-touch 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];
    });
}

我使用 SVProgressHUD 作为进度 HUD。我正在使用 dispatch_async()

调用方法 addProcess

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

最佳答案

一些事情:

  1. 关键观察是始终使用 dispatch_async,除非您需要 dispatch_sync。此处不需要同步操作,因此只需使用 dispatch_async 进行 UI 更新。

  2. 如果您从主队列运行 addProcess,它不需要将第一个 UI 更新分派(dispatch)回主队列。显然,如果您从后台队列运行它,您就可以。

  3. 最初的问题是在 addProcess 中调度到后台队列,这对我来说更有意义(很好地封装了所有 GCD 内容)。你已经更新了你的答案,说你正在通过 dispatch_async([self addProcess]) 调用它(我认为你的意思是全局队列,而不是主队列),我'我不那么疯狂了。我在下面的代码示例中解决了这两种情况。

所以,简而言之,如果您通过 [self addProcess] 调用它(而不将它本身分派(dispatch)到后台队列),我建议:

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

关于objective-c - 在主调度队列上显示 UI 元素会导致元素出现然后消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11889438/

相关文章:

ios - 如何使用 imageWithContentsOfFile 读取本地化图像

ios - 如何从 Swift View 模型绑定(bind)到 Obj-c View Controller ?

iphone - 如何检测前置或后置摄像头是否处于事件状态;以编程方式查找相机分辨率

iphone - 启动 AVAssetReader 停止回调到 Remote I/O AudioUnit

ios - iOS并发-未达到理论最大值附近的任何地方

swift 3 : capture strong self in @escaping closure without asynchronous work

Swift 3 并行 for/map 循环

ios - 解析从 AFNetworking 获取的 JSON 以显示在 UITableView 中

ios - 在 UITableView 中隐藏/显示单元格?

objective-c - 如何从 iOS 上的 GUI 元素合成图像?