当使用GCD调用时,UIWebView stringByEvaluatingJavaScriptFromString在iOS5.0 / 5.1上挂起

时间:2012-07-21 16:28:34

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

我在viewDidLoad中有以下代码,它在iOS 4.3上正常运行,但它挂在iOS 5 / 5.1上。在iOS 5 / 5.1上,显示警告对话框,但无法解除,UI线程冻结,无法单击“确定”按钮。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    dispatch_sync(dispatch_get_main_queue(), ^{
        [self.webview stringByEvaluatingJavaScriptFromString:@"alert('HELLO WORLD!')"];
    });
});

这是一个错误吗?

4 个答案:

答案 0 :(得分:18)

经过测试,我将其视为Bug,并将代码更改为

[webView performSelectorOnMainThread:@selector(stringByEvaluatingJavaScriptFromString:) withObject:js waitUntilDone:NO]

将解决它。

答案 1 :(得分:0)

- (void)viewDidAppear:(BOOL)animated中尝试

答案 2 :(得分:-1)

为什么你在这里使用GCD?

请记住,在GCD中,无论队列如何,都无法保证您的代码将调用哪个线程。我的猜测是你的DISPATCH_QUEUE_PRIORITY_DEFAULT代码恰好在主线程上运行,然后在dispatch_sync()调用中触发死锁。这可以通过检查调试器或Instruments中的线程状态来验证。

回到我原来的问题:你通过这些卷积得到什么而不是直接在主线程上调用方法?你会阻止任何一种方式。

您还可以将dispatch_sync()更改为dispatch_async() - 这也应该可以抑制死锁,但只有在您有其他并发需求并且不需要后台线程阻止时才应该这样做。

答案 3 :(得分:-1)

尝试

dispatch_async(dispatch_get_main_queue(), ^{
    [self.webview stringByEvaluatingJavaScriptFromString:@"alert('HELLO WORLD!')"];
});