使用GCD连续显示多个视图

时间:2015-02-10 06:51:05

标签: ios objective-c iphone uiwebview grand-central-dispatch

我有4个标签,所有标签都有UIWebView。我希望第一个标签应该立即加载和显示,而不必等待其他人加载。我在UITabBarController课程中做了这个:

for(UIViewController * viewController in  self.viewControllers){
        if(![[NSUserDefaults standardUserDefaults]boolForKey:@"isSessionExpired"])
        {
            if((int)[self.viewControllers indexOfObject:viewController] != 4)
            {
                viewController.tabBarItem.tag = (int)[[self viewControllers] indexOfObject:viewController];
                [viewController view];
            }
        }
    }

但主线程等待加载所有标签 我使用dispatch_async

尝试使用 GCD
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ // 1
        dispatch_async(dispatch_get_main_queue(), ^{
        UIViewController *firstContrl = [self.viewControllers objectAtIndex:0];
        firstContrl.tabBarItem.tag = (int)[[self viewControllers] indexOfObject:firstContrl];
        [firstContrl view];
        dispatch_async(dispatch_get_main_queue(), ^{ // 2
            UIViewController *secContrl = [self.viewControllers objectAtIndex:1];
            secContrl.tabBarItem.tag = (int)[[self viewControllers] indexOfObject:secContrl];
            [secContrl view];
            dispatch_async(dispatch_get_main_queue(), ^{ // 3
                UIViewController *thirdContrl = [self.viewControllers objectAtIndex:2];
                thirdContrl.tabBarItem.tag = (int)[[self viewControllers] indexOfObject:thirdContrl];
                [thirdContrl view];
                dispatch_async(dispatch_get_main_queue(), ^{ // 4
                    UIViewController *fourthContrl = [self.viewControllers objectAtIndex:3];
                    fourthContrl.tabBarItem.tag = (int)[[self viewControllers] indexOfObject:fourthContrl];
                    [fourthContrl view];
                });
            });
        });
    });
}); 

但这也不起作用。显示第一个标签需要相同的时间 如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

Ehm .. GCD UIWebView&#39> <{strong> -loadRequest:并不像您想象的那样有效。上面的所有代码都非常相同:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    dispatch_async(dispatch_get_main_queue(), ^{
        UIViewController *firstContrl = [self.viewControllers objectAtIndex:0];
        firstContrl.tabBarItem.tag = (int)[[self viewControllers] indexOfObject:firstContrl];
        [firstContrl view];

        UIViewController *secContrl = [self.viewControllers objectAtIndex:1];
        secContrl.tabBarItem.tag = (int)[[self viewControllers] indexOfObject:secContrl];
        [secContrl view];

        UIViewController *thirdContrl = [self.viewControllers objectAtIndex:2];
        thirdContrl.tabBarItem.tag = (int)[[self viewControllers] indexOfObject:thirdContrl];
        [thirdContrl view];

        UIViewController *fourthContrl = [self.viewControllers objectAtIndex:3];
        fourthContrl.tabBarItem.tag = (int)[[self viewControllers] indexOfObject:fourthContrl];
        [fourthContrl view];

    });
});

要解决您的问题,您需要实现队列取决于- (void)webViewDidFinishLoad:(UIWebView *)webView。这个想法是:

  1. 第一个视图控制器的webView开始加载请求 异步;
  2. 当加载(或失败)请求时,webView将通知您 委托;
  3. 使用webView通知所有其他视图控制器,让它们启动 加载他们的请求;
  4. 如果我是你,我会以下一个方式实施它:

    // FirstViewController.h
    extern NSString * const FirstViewControllerDidLoadWebView;
    
    // FirstViewController.m
    NSString * const FirstViewControllerDidLoadWebView=@"FirstViewControllerDidLoadWebView";
    - (void)webViewDidFinishLoad:(UIWebView *)webView
    {
    // notify other controllers, to let them load their web views:
    [[NSNotificationCenter defaultCenter] postNotificationName:FirstViewControllerDidLoadWebView
     object:nil];
    }
    - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
    {
        // loading failed. Try to load it few more times but anyway notify other controllers after:
    [[NSNotificationCenter defaultCenter] postNotificationName:FirstViewControllerDidLoadWebView
     object:nil];
    }
    

    之后,&#39;订阅&#39;所有其他(仅选项卡)查看FirstViewControllerDidLoadWebView通知的控制器,并在其到达后加载其WebView。

    有关详细信息,请查看NSNotificationCenterUIWebViewDelegate