UIWebView stringByEvaluatingJavaScriptFromString hangs on iOS5.0/5.1 when called using GCD
After test, I consider it as a Bug, and changing code to use
[webView performSelectorOnMainThread:@selector(stringByEvaluatingJavaScriptFromString:) withObject:js waitUntilDone:NO]
will solve it.
Deadlock with GCD and webView
This seems to simply be a bug in UIWebView. According to this question, it was introduced in iOS 5 and did not deadlock on iOS 4.3 and below.
Interestingly, presenting a UIAlertView right before the call to stringByEvaluatingJavaScriptFromString:
strangely prevents the deadlock:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *message = [[UIAlertView alloc] initWithTitle:@"Test"
message:@"Test"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[message show];
[theWebView stringByEvaluatingJavaScriptFromString:@"alert('hi');"];
});
});
However, my theory is this: When I pause execution after the deadlock occurs, I see that the WebThread is halted at __psynch_mutexwait
. Since the JavaScript engine is executed on different threads, it must tell the main thread to display the alert view. However, stringByEvaluatingJavaScriptFromString:
is a blocking call that returns a value. The value can only be returned once the alert is dismissed by clicking OK. This is where the deadlock seemingly occurs: From a different thread we tell the main thread to tell the web view to run JavaScript (which happens on yet another thread), which in turn tells the main thread to display an alert view, which can only deliver its return value back to JavaScript once OK is clicked. And only when the call to stringByEvaluatingJavaScriptFromString:
returns is the block that we passed to GCD complete.
It must be a bug, though. It is strange that the deadlock doesn't occur when I display a UIAlertView first. Maybe iOS puts the second alert view on some kind of queue in that case, which prevents the deadlock. Odd!
Why am I getting a symbol lookup error?
I put the error through c++filt
, it says that the mangled name stands for
BCGateway::instance()
This suggests that you call BCGateway::instance()
somewhere and forgot to link against BCGateway.o
or you even forgot to define BCGateway::instance()
.
Related Topics
Chrome for iOS User Agent on iPad
Programmatically Sending an App to Background
What Is Difference Between Self.Timer = Nil VS [Self.Timer Invalidate] in iOS
How to Make a Conical Gradient in iOS Using Core Graphics/Quartz 2D
Parsing JSON Using the New Swift 3 and Alamofire
Admob 7.3.1 and Swift 2.0 - Module Not Found
Autolayout Ignores Multi-Line Detailtextlabel When Calculating Uitableviewcell Height (All Styles)
Stop Skaction That Repeatsforever - Sprite Kit
Uiwebview Stringbyevaluatingjavascriptfromstring Hangs on iOS5.0/5.1 When Called Using Gcd
Animating Calayer's Shadowpath Property
How to Get an Error Description When Playback Fails on Mpmovieplayercontroller
How Could You Make a Uilabel Wrap Around an Image (Like Shown)
iOS Multiple Right and Left Align on Same Line
How to Reload Tableview of Another Uiviewcontroller in Current Viewcontroller