【问题标题】:How to force main thread to process everything? Problem with UIWebView如何强制主线程处理所有内容? UIWebView 的问题
【发布时间】:2011-08-05 13:32:06
【问题描述】:

我想在 UIWebView 中加载一些 HTML:

- (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    
}

【问题讨论】:

    标签: iphone objective-c multithreading uiwebview


    【解决方案1】:

    我怀疑您是否可以强制主线程处理UIWebView 的工作,但您可以等到UIWebView 完成后再执行您的“其他耗时代码”。为UIWebView 设置委托并实现webViewDidFinishLoad:,让它调用一个方法来执行耗时的任务。

    【讨论】:

    • 感谢您的回答!在 webViewDidFinishLoad 中执行“其他耗时代码”的想法很好,但它可能有点复杂,因为我将“loadHTMLString”调用到多个 UIWebView 的循环中。而且我的整个代码中有很多 UIWebViews 并且 webViewDidFinishLoad 被调用了很多时间。如果应该调用“其他耗时的代码”,我会设置标志......强制主线程处理的可能性对我来说会容易得多。
    【解决方案2】:

    使用同一个线程来处理所有事情(尤其是耗时的东西)不是一个好主意。

    当你在响应 UI 的线程上做一些耗时的事情时,整个 UI 将被冻结,它无法给用户任何响应,例如触摸时按钮不会改变颜色。 所以你应该把耗时的东西和 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
    });
    

    请注意,上例中的默认队列会并发处理任务,如果您想自己管理队列,可以这样创建:

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

    更多详情请关注Session 211 of WWDC 2010 Session Videos: Simplifying iPhone App Development with Grand Central Dispatch

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-23
      • 1970-01-01
      • 2019-06-11
      • 2012-09-16
      • 1970-01-01
      相关资源
      最近更新 更多