等待子视图显示,然后处理,然后删除子视图

时间:2014-12-05 22:34:53

标签: ios objective-c xcode multithreading ios8

我花了一周的时间试图弄清楚如何做到这一点。

我想要做的是显示子视图,然后对后端进行http调用,然后删除子视图。

...
//Display view
[superView addSubview:blurredOverlay];
[superView bringSubviewToFront:blurredOverlay];

//After blurredOverlay is displayed, Try to login the user
dispatch_group_t d_group = dispatch_group_create();
dispatch_queue_t bg_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_async(d_group, bg_queue, ^{
    //Try to login user
    success = [self loginUser];
    NSLog(@"Success=%i", success);
    [NSThread sleepForTimeInterval:10.0]; //here to force thread to not return immediatly
});
dispatch_group_wait(d_group, DISPATCH_TIME_FOREVER);

//Remove the view after the thread is done processing
[blurredOverlay removeFromSuperview];

这不起作用。如果我有

[blurredOverlay removeFromSuperview];

取消注释,blurOverlay永远不会显示。如果我将它评论出来,会显示blurOvleray,但我显然无法将其删除。

我需要先显示blurOverlay,然后尝试登录用户(显示blurOverlay时),登录用户返回后,删除模糊显示。

1 个答案:

答案 0 :(得分:1)

您正在将此块分派给异步队列。您的主线程将不会停止等待该块完成。 但你已经知道了。这就是为什么在后台任务完成之前使用调度组来阻止主线程的原因 该方法的问题在于,只有在runloop完成当前迭代后才刷新UI。直到你的方法离开时才会发生这种情况。

这是代码运行时发生的情况:

  • UI由系统更新
  • 输入了您的方法
    • 添加视图
    • 调度块
    • 等待阻止完成
    • 删除视图
  • 留下你的方法
  • UI由系统更新

你看到了问题吗?在添加视图和删除视图之间不会更新UI。

这是你应该做的。您添加视图。使用您的任务调度块,使其在后台运行。在该背景块的末尾,您将分派另一个块,该块将在后台任务完成时运行。该块在主线程上运行并删除您的视图。

[superView addSubview:blurredOverlay];
dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(backgroundQueue, ^{

    // run your web request here
    [NSThread sleepForTimeInterval:10.0];

    // task is done
    dispatch_async(dispatch_get_main_queue(), ^{
        // UI updates have to run on the main thread, so dispatch the removal
        [blurredOverlay removeFromSuperview];
    });
});