使用GCD连续显示多个视图 [英] Display multiple views serially using GCD
问题描述
我有4个标签,并且都具有UIWebView
.我希望第一个选项卡应该加载并立即显示,而不必等待其他人加载.为此,我在UITabBarController
类中进行了此操作:
I have 4 tabs and all have UIWebView
. I want that the first tab should load and displayed immediately without waiting for others to load. For which I did this in UITabBarController
class:
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
But the main thread waits for all tabs to load.
I tried this with GCD using dispatch_async
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];
});
});
});
});
});
但这也不起作用.显示第一个标签需要花费相同的时间.
该如何解决?
But this doesn't work either. It takes the same time to display the first tab.
How can this be fixed?
推荐答案
Ehm .. GCD 和 UIWebView的 -loadRequest:
无法正常工作.上面的所有代码都等于:
Ehm.. GCD and UIWebView's -loadRequest:
doesn't work as you think. All the code above is pretty equal to:
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
实施队列.这个想法是:
To solve your problem you need to implement queue depends on - (void)webViewDidFinishLoad:(UIWebView *)webView
. The idea is:
- 第一个视图控制器的webView开始加载请求 异步;
- 加载请求(或失败)后,webView会通知您 代表;
- 使用webView通知所有其他视图控制器,以使其启动 加载他们的请求;
- First view controller's webView starts loading request asynchronously;
- When request is loaded (or failed), webView will notify your delegate;
- Notify all other view controllers with webView, to let them start loading their requests;
如果我是你,我会以另一种方式实现它:
If I were you, I would implement it in next way:
// 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];
}
此后,为所有其他(仅选项卡)视图控制器订阅" FirstViewControllerDidLoadWebView
通知,并在到达它们后加载其WebView.
After that, 'subscribe' all other(only tabs) view controllers for FirstViewControllerDidLoadWebView
notification and load their WebView after it arrives.
有关更多详细信息,请检查 NSNotificationCenter 和 UIWebViewDelegate
For more details check NSNotificationCenter and UIWebViewDelegate
这篇关于使用GCD连续显示多个视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!