2013-11-08 1 views
18

У меня есть приложение для iPad, которое находится в App Store уже около трех месяцев, и я получаю некоторые странные отчеты о сбоях, которые я не могу понять. Это не так часто, с момента запуска запускалось около 15-20 экземпляров, но до сих пор достаточно частым, чтобы на самом деле обмануть меня. Сбои немного отличаются (см. Следы стека ниже), но поскольку они связаны с WebCore, я предполагаю, что они имеют отношение к использованию UIWebView в приложении и могут иметь общую причину, хотя я не на 100% положителен , Цель развертывания приложения - iOS 6.0, но сбои появляются на iPad 2, iPad 3 и iPad Mini, исключительно на iOS 7.Неустранимая сбой веб-камеры

В приложении есть только одно место, где я использую веб-просмотр, для отображения новостей статьи из разных источников. У меня есть один контроллер вида для этого, который имеет вид UIWebView. Существует один экземпляр этого контроллера представления, который живет во всем приложении, каждый раз, когда выбирается новая статья, существующий веб-просмотр перезагружается с URL-адресом недавно выбранной статьи.

В одном из предложенных решений, основанных на обсуждении вопросов WebCore, предложено установить для свойства delegate свойства webviews nil в методе контроллера dealloc. К сожалению, я не думаю, что это применимо в моем случае, потому что диспетчер представлений не освобождается в течение жизненного цикла приложения.
Другой проблемой могут быть неправильные веб-страницы с плохими ссылками на изображение в CSS (loadPendingImages crash). Хотя я не мог найти такую ​​страницу.
Кроме того, я дважды проверял и выполнял операции, связанные с веб-просмотром, в основном потоке.

Аварии являются

Exception Type: EXC_BAD_ACCESS 
Code: KERN_INVALID_ADDRESS 

со следующими трассировки стека (полные, here)

0 WebCore WebCore::StyleResolver::applyMatchedProperties(WebCore::StyleResolver::MatchResult const&, WebCore::Element const*) + 815 
1 WebCore WebCore::StyleResolver::applyMatchedProperties(WebCore::StyleResolver::MatchResult const&, WebCore::Element const*) + 788 
2 WebCore WebCore::StyleResolver::styleForElement(WebCore::Element*, WebCore::RenderStyle*, WebCore::StyleSharingBehavior, WebCore::RuleMatchingBehavior, WebCore::RenderRegion*) + 948 
3 WebCore WebCore::Document::styleForElementIgnoringPendingStylesheets(WebCore::Element*) + 96 
4 WebCore WebCore::Element::computedStyle(WebCore::PseudoId) + 142 
5 WebCore WebCore::ComputedStyleExtractor::propertyValue(WebCore::CSSPropertyID, WebCore::EUpdateLayout) const + 458 

и

0 WebCore WebCore::StyleResolver::loadPendingImages() + 1153 
1 WebCore WebCore::ResourceRequestBase::~ResourceRequestBase() + 104 
2 WebCore WebCore::StyleResolver::applyMatchedProperties(WebCore::StyleResolver::MatchResult const&, WebCore::Element const*) + 782 
3 WebCore WebCore::StyleResolver::styleForElement(WebCore::Element*, WebCore::RenderStyle*, WebCore::StyleSharingBehavior, WebCore::RuleMatchingBehavior, WebCore::RenderRegion*) + 948 
4 WebCore WebCore::Document::styleForElementIgnoringPendingStylesheets(WebCore::Element*) + 96 
5 WebCore WebCore::Element::computedStyle(WebCore::PseudoId) + 142 

и

0 WebCore WebCore::StyleResolver::adjustRenderStyle(WebCore::RenderStyle*, WebCore::RenderStyle*, WebCore::Element*) + 19 
1 WebCore WebCore::StyleResolver::styleForElement(WebCore::Element*, WebCore::RenderStyle*, WebCore::StyleSharingBehavior, WebCore::RuleMatchingBehavior, WebCore::RenderRegion*) + 964 
2 WebCore WebCore::Document::styleForElementIgnoringPendingStylesheets(WebCore::Element*) + 96 
3 WebCore WebCore::Element::computedStyle(WebCore::PseudoId) + 142 
4 WebCore WebCore::ComputedStyleExtractor::propertyValue(WebCore::CSSPropertyID, WebCore::EUpdateLayout) const + 458 
5 WebCore WebCore::CSSComputedStyleDeclaration::getPropertyValue(WebCore::CSSPropertyID) const + 42 

и

0 WebCore WebCore::TimerBase::heapDeleteMin() + 37 
1 WebCore WebCore::ThreadTimers::sharedTimerFiredInternal() + 94 
2 WebCore WebCore::ThreadTimers::sharedTimerFiredInternal() + 94 
3 WebCore WebCore::timerFired(__CFRunLoopTimer*, void*) + 24 
4 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 14 
5 CoreFoundation __CFRunLoopDoTimer + 782 

Кто-нибудь испытал подобные аварии? Если да:
1. Есть ли способы их тиражирования?
2. Как можно отлаживать их без их репликации?
3. Какие исправления решают проблемы?

Спасибо!

+0

У iOS 7 есть несколько серьезных проблем с графическим рендерингом. Проблема, которую вы пытаетесь отследить, вероятна и уровень ОС (уровень SDK). Чтобы осмелиться догадаться, есть некоторые CSS-преобразования или анимации, которые вызывают крах. Ваша единственная надежда изолировать причину - найти страницу, которая ее вызывает, и даже тогда вы, вероятно, ничего не сможете с этим поделать. – Holly

+0

Да, к сожалению, я еще не успел повторить его, и с тех пор, как я загружаю новостные статьи из разных (30+) источников новостей, у меня есть чувство, что я не смогу сделать это в ближайшее время. Если ни у кого больше не будет лучшего представления о том, что может происходить здесь, нам придется подождать iOS 7.1 и посмотреть, не затрагивают ли они какие-либо из этих проблем. –

+0

Я копировал эту ошибку в кордове ios7 с помощью window.requestAnimationFrame в цикле рекурсии для создания анимированных смайликов спрайтов. Кажется, что это может произойти, когда приложение просыпается от долгого сна и снова пытается оживить. – Abadaba

ответ

5

У меня была такая же проблема в приложении, над которым я работал, это странно произошло только на старых устройствах под управлением iOS 7. Я подозреваю, что это связано с тем, что они не могут идти в ногу со временем.

У меня был UITableView, где один из рядов открыл бы UIViewController, у которого был UIWebView на нем для пользовательских объявлений. То, что я нашел, это то, что на старых устройствах объекты и память, где они были свободны гораздо чаще, чем я видел на других платформах. Я мог очень легко подражать краху на iPhone 4, введя/выйдя из экрана 2 или 3 раза. Где в качестве iPhone 5 я потратил 15 минут на то, чтобы сделать то же самое, и не мог этого винить.

Я знаю, что вы можете почувствовать, что ваш контроллер не является dealloc'd, но это действительно звучит так, как если бы оно было, или какая-либо ссылка была удалена. Я также видел, что мои ссылки делегатов несколько раз исчезают в этом приложении.

Мой совет и то, что сработало для меня, - это остановить выполнение веб-просмотров и установить все на nil, когда сможете.

В одном случае на моем приложении, которое я выбрал, чтобы сделать это на viewWillDisappear обратном вызове, потому что в моем обстоятельстве он ушел от пользователя и воссоздан позже, так что я гашусь все, как так:

[webView stopLoading]; 

self.webView.delegate = nil; 
self.webView = nil; 
+0

Спасибо за подсказку, Саймон. Я должен попробовать это. К сожалению, поскольку я не могу реплицировать проблему, я не смогу узнать, работает это или нет, по крайней мере, пока я не выпущу обновление для своего приложения. –

+0

@ BotondSzékely надеюсь, что это поможет вам, одним быстрым способом было бы сделать то, что я сделал, и отправить сообщение всем своим друзьям и попросить занять более старое устройство в течение нескольких дней. Я нахожу iPhone 4 в ручке iOS 7 очень плохо –

+1

Внимание к любому, кто просто берет этот код выше как есть. Вы можете ввести ошибки, если у вас есть экраны, которые пользователь может получить с экрана с веб-просмотром. Например, представьте, что у вас есть кнопка панели навигации, которая нажимает другой экран на навигационном контроллере. Он будет вызывать 'viewWillDisappear' и очистить' self.webView.delegate' и 'self.webView'. Затем, когда вы вернетесь на экран веб-просмотра, вы все равно увидите веб-просмотр, но любой код, который ссылается на 'self.webView', ничего не сделает. –

1

Посмотрите на ваш код Javascript-to-Objective-C, и если вы выполняете/вызываете код javascript, убедитесь, что скрипт не вызывает новые вызовы Objective-C.

Это правильное использование:

Javascript >> Objective-C 

Objective-C >> Javascript 

Это причина аварии:

Objective-C >> Javascript >> Objective-C (здесь возможна авария в зависимости от некоторых условий гонки)

Solution специфичен для вашего кода проекта. Но проще всего обернуть весь Javascript в setTimeout(), чтобы запланировать выполнение в потоке Javascript. Вот простой пример, код Objective-C должен выполнить этот скрипт:

storeUserPhoneNumber("011 123 4567"); 

Крах произойдет, если storeUserPhoneNumber функция перезванивает кода Objective-C (прямо или косвенно) в своем теле. Чтобы исправить этот только код обертывания в setTimeout следующим образом:

setTimeout(function() { 
    storeUserPhoneNumber("011 123 4567"); 
}, 0); 
Смежные вопросы