2011-08-05 22 views
0

问题,我想加载一些HTML在一个UIWebView:如何强制主线程处理所有内容?有一个UIWebView

- (IBAction)buttonClicked:(id)sender { 
    [webView loadHTMLString:@"Hello World" baseURL:nil]; 
    // a lot of other time-consuming code that has to perform in main thread 
} 

的问题是,该UIWebView的开始装车后“等费时的”代码完成。我想要的是,UIWebView直接开始加载。 UIWebView是否等待主线程并在主线程中的所有事件被处理后开始加载?

我可以强制主线程处理所有事情吗?

- (IBAction)buttonClicked:(id)sender { 
    [webView loadHTMLString:@"Hello World" baseURL:nil]; 
    // !!! main thread, please PERFORM everything until here BEFORE going on !!! 
    // a lot of other time-consuming code that has to perform in main thread 
} 

PS:以下解决方法的工作原理,但我认为这不是最好的解决办法;-)

- (IBAction)buttonClicked:(id)sender { 
    [webView loadHTMLString:@"Hello World" baseURL:nil]; 
    [NSThread detachNewThreadSelector:@selector(startNewThread) toTarget:self withObject:nil]; 
} 

- (void)startNewThread { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    [NSThread sleepForTimeInterval:1]; 
    [self performSelectorOnMainThread:@selector(goBackToMainthread) withObject:nil waitUntilDone:NO]; 
    [pool release];  
} 

- (void)goBackToMainthread { 
    // a lot of other time-consuming code that has to perform in main thread  
} 

回答

1

使用相同的线程来处理一切(特别是耗时的东西)不是一个好主意。

当您在线程响应用户界面时耗费了大量时间,整个用户界面将被冻结,并且无法向用户提供任何响应,例如,触摸它时,按钮不会改变颜色。 所以你应该在不同的线程上分离耗时的东西和UI东西。

接下来,UIKit不是线程安全的(除了绘制到图形上下文),这意味着您不应该在主线程外执行任何与UI相关的任何操作。

所以结论是:在另一个线程上处理耗时的东西,而不是主线程。 这部分是很容易的iOS4的GCD,下面的代码应该做的:

#include <dispatch/dispatch.h> 

[webView loadHTMLString:@"Hello World" baseURL:nil]; 
dispatch_queue_t myQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
dispatch_async(myQueue, ^{ 
    //Do something time consuming here 
}); 

注意,在上面的例子中默认队列会同时处理的任务,如果你要管理的队列(S)你自己,你可以这样创建:

dispatch_queue_t myQueue = dispatch_queue_create("com.mycompany.myqueue", 0); 

更多细节可以在Session 211 of WWDC 2010 Session Videos on iTunes

3

我怀疑你可以强制主线程来处理工作UIWebView,但您可以等到UIWebView完成后再执行“其他耗时代码”。将代理设置为UIWebView并实施webViewDidFinishLoad:,使其调用执行耗时任务的方法。

+0

找到谢谢您的回答!在webViewDidFinishLoad中执行“其他耗时代码”的想法很好,但它可能有点复杂,因为我将“loadHTMLString”称为多个UIWebView的循环。我的整个代码中有很多UIWebViews,而且webViewDidFinishLoad被称为很多时间。如果应该调用“其他耗时的代码”,我会放置标志......强制主线程处理的可能性对我来说会更容易。 – Manni

相关问题