I've found an issue that seems to be causing a deadlock in WebKit. If I run this code from my main thread, I rightly see an alert. I can tap on the "OK" button on the alert and it dismisses and all is working well:
[theWebView stringByEvaluatingJavaScriptFromString:@"alert('hi');"];
If I make a slight modification, then the alert message still appears, but the OK button cannot be tapped on - you cannot dismiss the alert and if you break into the app it is hung in the stringByEvaluatingJavaScriptFromString
call:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
[theWebView stringByEvaluatingJavaScriptFromString:@"alert('hi');"];
});
});
The only different in these two is that in the second one, it is running the JS in the main thread in the context of a dispatch queue.
On the other hand, if I do the following, then the hang does not occur:
- (void) showHi:(id) it
{
[(UIWebView*)it stringByEvaluatingJavaScriptFromString:@"alert('hi');"];
}
....
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self performSelectorOnMainThread:@selector(showHi:) withObject:theWebView waitUntilDone:NO];
});
Can someone shine some light on what is going wrong to cause the hang?
EDIT:
Related questions:
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
Very similar question:
UIWebView stringByEvaluatingJavaScriptFromString hangs on iOS5.0/5.1 when called using GCD
I think it was stated in webview class reference
Now, For your case of dead lock you can simulate the same by replacing this
[self performSelectorOnMainThread:@selector(showHi:) withObject:theWebView waitUntilDone:NO];
with
performSelector:withObject:afterDelay:inModes:
.
With Respective mode by default it was NSDefaultRunLoopMode
and which was atomic in nature whereas in your nonatomic case of dispatch_get_main_queue()
you have to change the current dispatch mode of threading.
I hope it remained informative. Also, more suggestions are welcomed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With