Ответ 1
После теста я рассматриваю его как ошибку и изменяя код для использования
[webView performSelectorOnMainThread:@selector(stringByEvaluatingJavaScriptFromString:) withObject:js waitUntilDone:NO]
решит его.
У меня есть следующий код в 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!')"];
});
});
Это ошибка?
После теста я рассматриваю его как ошибку и изменяя код для использования
[webView performSelectorOnMainThread:@selector(stringByEvaluatingJavaScriptFromString:) withObject:js waitUntilDone:NO]
решит его.
Попробуйте вместо этого - (void)viewDidAppear:(BOOL)animated
Почему вы вообще используете GCD?
Помните, что в GCD нет гарантии, на какую нить будет вызывать ваш код, независимо от очереди. Я предполагаю, что ваш код DISPATCH_QUEUE_PRIORITY_DEFAULT
запускается в основном потоке, который затем запускает тупик вашего вызова dispatch_sync()
. Это можно проверить, просмотрев состояния потоков в отладчике или инструментах.
Что возвращается к моему первоначальному вопросу: что вы получаете, выполняя эти свертки вместо того, чтобы просто вызвать метод непосредственно в основном потоке? Вы будете блокировать в любом случае.
Вы также можете изменить dispatch_sync()
на dispatch_async()
, что также должно блокировать тупик, но это должно быть сделано только в том случае, если у вас есть другие concurrency и не требуется фоновый поток для блокировки.
Try
dispatch_async(dispatch_get_main_queue(), ^{
[self.webview stringByEvaluatingJavaScriptFromString:@"alert('HELLO WORLD!')"];
});