I have the following code in viewDidLoad
, which works properly on iOS 4.3, but it hangs on iOS 5/5.1. On iOS 5/5.1, the alert dialog is shown but can not be dismissed, the UI thread freezes, the OK button just can not be clicked.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_sync(dispatch_get_main_queue(), ^{
[self.webview stringByEvaluatingJavaScriptFromString:@"alert('HELLO WORLD!')"];
});
});
Is this a bug?
After test, I consider it as a Bug, and changing code to use
[webView performSelectorOnMainThread:@selector(stringByEvaluatingJavaScriptFromString:) withObject:js waitUntilDone:NO]
will solve it.
Try it in - (void)viewDidAppear:(BOOL)animated
instead
Why are you using GCD at all here?
Remember that in GCD there is no guarantee which thread your code will called on, regardless of queue. My guess is that your DISPATCH_QUEUE_PRIORITY_DEFAULT
code happens to be running on the main thread, which is then triggering a deadlock on your dispatch_sync()
call. This could be verified by examining your thread states in the debugger or Instruments.
Which gets back to my original question: what do you get by doing these convolutions instead of just calling the method directly on the main thread? You are going to block either way.
You can also change your dispatch_sync()
to dispatch_async()
- that should also suppress a deadlock, but should only be done if you have other concurrency needs and don't need a background thread to block.
Try
dispatch_async(dispatch_get_main_queue(), ^{
[self.webview stringByEvaluatingJavaScriptFromString:@"alert('HELLO WORLD!')"];
});