This seems to be just a bug in the UIWebView. According to this question , it was introduced in iOS 5 and made a dead end not on iOS 4.3 or lower.
Interestingly, the UIAlertView view right before calling stringByEvaluatingJavaScriptFromString: strangely prevents a dead end:
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 a dead end, I see that WebThread is stopped at __psynch_mutexwait . Because the JavaScript engine runs in different threads, it must point to the main thread to display the alert view. However, stringByEvaluatingJavaScriptFromString: is a blocking call that returns a value. The value can only be returned after the warning has been dismissed by clicking OK. This is where a dead end arises: from another thread, we tell the main thread to tell the web browser that it is running JavaScript (what happens in the other thread), which in turn tells the main thread to display a warning, which can return the return value back to JavaScript after clicking OK. And only when the call to stringByEvaluatingJavaScriptFromString: returns, is it the block that we passed to the GCD.
There must be a mistake. It is strange that a dead end does not occur when I first show the UIAlertView. Perhaps, in this case, iOS puts the second type of warning on some line, which prevents a dead end. Weird!
source share