ios – 使用GCD和webView进行死锁

ios – 使用GCD和webView进行死锁,第1张

概述我发现了一个似乎导致WebKit陷入僵局的问题.如果我从我的主线程运行此代码,我正确地看到一个警报.我可以点击警报上的“确定”按钮,它会解散并且一切正常: [theWebView stringByEvaluatingJavaScriptFromString:@"alert('hi');"]; 如果我进行了一些修改,那么仍然会出现警告消息,但是无法点击“确定”按钮 – 您无法关闭警报,如果您闯入应用 我发现了一个似乎导致WebKit陷入僵局的问题.如果我从我的主线程运行此代码,我正确地看到一个警报.我可以点击警报上的“确定”按钮,它会解散并且一切正常:
[theWebVIEw stringByEvaluatingJavaScriptFromString:@"alert('hi');"];

如果我进行了一些修改,那么仍然会出现警告消息,但是无法点击“确定”按钮 – 您无法关闭警报,如果您闯入应用程序,它将挂在stringByEvaluatingJavaScriptFromString调用中:

dispatch_async(dispatch_get_global_queue(disPATCH_QUEUE_PRIORITY_DEFAulT,0),^{    dispatch_async(dispatch_get_main_queue(),^{        [theWebVIEw stringByEvaluatingJavaScriptFromString:@"alert('hi');"];    });});

这两者中唯一不同的是,在第二个中,它在调度队列的上下文中在主线程中运行Js.

另一方面,如果我执行以下 *** 作,则不会发生挂起:

- (voID) showHi:(ID) it{    [(UIWebVIEw*)it stringByEvaluatingJavaScriptFromString:@"alert('hi');"];}....dispatch_async(dispatch_get_global_queue(disPATCH_QUEUE_PRIORITY_DEFAulT,^{    [self performSelectorOnMainThread:@selector(showHi:) withObject:theWebVIEw waitUntilDone:NO];});

有人可以对导致挂起的问题有所了解吗?

编辑:

相关问题:

Perform UI Changes on main thread using dispatch_async or performSelectorOnMainThread?
Whats the difference between performSelectorOnMainThread and dispatch_async on main queue?
Grand Central Dispatch (GCD) vs. performSelector – need a better explanation

非常相似的问题:

UIWebView stringByEvaluatingJavaScriptFromString hangs on iOS5.0/5.1 when called using GCD

解决方法 这似乎只是UIWebVIEw中的一个错误.根据 this question,它是在iOS 5中引入的,并没有在iOS 4.3及更低版本上死锁.

有趣的是,在调用stringByEvaluatingJavaScriptFromString之前呈现UIAlertVIEw:奇怪地防止了死锁:

dispatch_async(dispatch_get_global_queue(disPATCH_QUEUE_PRIORITY_DEFAulT,^{        UIAlertVIEw *message = [[UIAlertVIEw alloc] initWithTitle:@"Test"                                                          message:@"Test"                                                         delegate:nil                                                cancelbuttonTitle:@"OK"                                                otherbuttonTitles:nil];        [message show];        [theWebVIEw stringByEvaluatingJavaScriptFromString:@"alert('hi');"];    });});

但是,我的理论是这样的:当我在死锁发生后暂停执行时,我看到WebThread在__psynch_mutexwait停止.由于JavaScript引擎在不同的线程上执行,因此它必须告诉主线程显示警报视图.但是,stringByEvaluatingJavaScriptFromString:是一个返回值的阻塞调用.只有在单击“确定”关闭警报后才能返回该值.这就是死锁似乎发生的地方:从另一个线程我们告诉主线程告诉web视图运行JavaScript(发生在另一个线程上),这反过来告诉主线程显示一个警报视图,该视图只能单击“确定”后,将其返回值返回到JavaScript.只有当对stringByEvaluatingJavaScriptFromString:的调用返回时,我们传递给GCD的块才完成.

但它必定是一个BUG.奇怪的是,当我首先显示UIAlertVIEw时,不会发生死锁.在这种情况下,iOS可能会在某种队列上放置第二个警报视图,从而防止死锁.奇!

总结

以上是内存溢出为你收集整理的ios – 使用GCD和webView进行死锁全部内容,希望文章能够帮你解决ios – 使用GCD和webView进行死锁所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1114467.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存