Uiwebview Stringbyevaluatingjavascriptfromstring Hangs on iOS5.0/5.1 When Called Using Gcd

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



Leave a reply



Submit