Ios 使用GCD连续显示多个视图
我有4个选项卡,所有选项卡都有Ios 使用GCD连续显示多个视图,ios,objective-c,iphone,uiwebview,grand-central-dispatch,Ios,Objective C,Iphone,Uiwebview,Grand Central Dispatch,我有4个选项卡,所有选项卡都有UIWebView。我希望第一个选项卡应该立即加载和显示,而不必等待其他人加载。为此,我在UITabBarController类中执行了以下操作: for(UIViewController * viewController in self.viewControllers){ if(![[NSUserDefaults standardUserDefaults]boolForKey:@"isSessionExpired"]) {
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\u 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];
});
});
});
});
});
但这也不行。显示第一个选项卡所需的时间相同。如何解决这个问题?EhmGCD和UIWebView的
-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
。这个想法是:
// 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];
}
在此之后,“订阅”所有其他(仅选项卡)视图控制器的firstviewcontrolleridloadwebview
通知,并在通知到达后加载其WebView
要了解更多详细信息,请检查和我有点不清楚,问题出在哪里?您想让您的
UIWebView
立即开始显示某些web内容吗?@workenstein:是的。现在所有选项卡都在同时加载。我希望最初的第一个选项卡,即第一个UIWebView应该加载并显示,以便它对用户是活动的。还有其他的。没有你所有的自定义代码,它是如何工作的?在“不等待别人加载”的情况下,很难理解这一部分。这实际上对我很有用。谢谢UIWebView需要一些时间才能加载。我已经问过了。但是是的,现在我看到了很大的时差。首先加载并显示视图,然后加载其余视图。再次感谢。如果我们使用NSOperationQueue和NSOperations创建自己的结构,为什么不呢?添加依赖项(n+1)请求取决于n个操作(这意味着第二个操作取决于第一个操作)。依赖项将有助于加载1stViewController,然后将为2ndViewController启动第二个操作,依此类推。因此,您的加载过程将是序列化、快速、单向和同步的。@t当然,您可以随意以任何方式实现它。我刚刚写下了主要思想,让您自行决定如何实施。但在这里,操作看起来有点过于复杂。