UIWebView stringByEvaluatingJavaScriptFromString зависает на iOS5.0/5.1 при вызове с использованием GCD

У меня есть следующий код в viewDidLoad, который корректно работает на iOS 4.3, но он зависает на iOS 5/5.1. На iOS 5/5.1 отображается диалоговое окно предупреждения, но его нельзя отменить, поток пользовательского интерфейса замерзает, кнопка "ОК" просто не может быть нажата.

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    dispatch_sync(dispatch_get_main_queue(), ^{
        [self.webview stringByEvaluatingJavaScriptFromString:@"alert('HELLO WORLD!')"];
    });
});

Это ошибка?

Ответ 1

После теста я рассматриваю его как ошибку и изменяя код для использования

[webView performSelectorOnMainThread:@selector(stringByEvaluatingJavaScriptFromString:) withObject:js waitUntilDone:NO]

решит его.

Ответ 2

Попробуйте вместо этого - (void)viewDidAppear:(BOOL)animated

Ответ 3

Почему вы вообще используете GCD?

Помните, что в GCD нет гарантии, на какую нить будет вызывать ваш код, независимо от очереди. Я предполагаю, что ваш код DISPATCH_QUEUE_PRIORITY_DEFAULT запускается в основном потоке, который затем запускает тупик вашего вызова dispatch_sync(). Это можно проверить, просмотрев состояния потоков в отладчике или инструментах.

Что возвращается к моему первоначальному вопросу: что вы получаете, выполняя эти свертки вместо того, чтобы просто вызвать метод непосредственно в основном потоке? Вы будете блокировать в любом случае.

Вы также можете изменить dispatch_sync() на dispatch_async(), что также должно блокировать тупик, но это должно быть сделано только в том случае, если у вас есть другие concurrency и не требуется фоновый поток для блокировки.

Ответ 4

Try

dispatch_async(dispatch_get_main_queue(), ^{
    [self.webview stringByEvaluatingJavaScriptFromString:@"alert('HELLO WORLD!')"];
});