不可重现的networking核心崩溃
我有一个iPad应用程序,在App Store里已经有三个月的时间了,我收到了一些我不知道的奇怪的崩溃报告。 这些并不常见,自推出以来已经有15-20个实例,但仍然频繁发生,实际上让我感到不安。 崩溃是略有不同(见下面的堆栈跟踪),但由于他们与WebCore
相关,我猜他们必须在应用程序中使用UIWebView
,可能有一个共同的原因,但我不是100%正面。 该应用程序的部署目标是iOS 6.0,但崩溃出现在iOS 2上的iPad 2,iPad 3和iPad Mini上。
在我使用webview的应用程序中,只有一个地方显示各种来源的新闻文章网页。 我有一个视图控制器,它有一个UIWebView
作为其视图。 有一个这个视图控制器的实例遍布整个应用程序,每次select一个新的文章,现有的webview重新加载与新select的文章的url。
基于围绕WebCore问题的讨论提出的解决scheme之一build议在控制器的dealloc
方法中将webviews delegate
属性设置nil
。 不幸的是,我不认为这适用于我的情况,因为在应用程序的生命周期中,视图控制器没有被取消分配。
另一个问题可能是不正确的网页在CSS(loadPendingImages崩溃)中具有不良的图像引用。 尽pipe如此,我还是找不到这样一个页面。
此外,我仔细检查,并确保在主线程上做webview相关的操作。
崩溃是
Exception Type: EXC_BAD_ACCESS Code: KERN_INVALID_ADDRESS
与下面的堆栈跟踪(全部在这里 )
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.如何在不复制它们的情况下进行debugging?
3.什么修复解决了这个问题?
谢谢!
我在一个应用程序中遇到了同样的问题,奇怪的是,这个问题只发生在运行iOS 7的旧设备上。我怀疑这跟他们无法跟上。
我所拥有的是一个UITableView
其中一行将打开一个UIViewController
的UIWebView
的自定义广告。 我发现,在较旧的设备上,对象和内存的释放比其他平台上的要多得多。 我可以很容易地在iPhone 4上通过进出屏幕2或3次来模仿崩溃。 作为一个iPhone 5我花了15分钟做同样的事情,不能错。
我知道你可能觉得你的控制器没有被解除分配,但是它确实听起来好像有些引用正在被丢弃,我也看到了我的代理引用在这个应用程序中也消失了几次。
我的build议和我的工作是停止执行的web视图,并设置所有的东西,当你可以。
在我的应用程序中的一个实例中,我select在viewWillDisappear
callbackviewWillDisappear
上执行该操作,因为在我的情况下,它已经从用户身上消失并稍后重新创build,所以我将所有内容都清空了:
[webView stopLoading]; self.webView.delegate = nil; self.webView = nil;
看看你的Javascript-to-Objective-C代码,如果你正在执行/调用JavaScript代码,请确保脚本不会调用Objective-C的新调用。
这是正确的用法:
Javascript >> Objective-C Objective-C >> Javascript
这是崩溃的原因:
Objective-C >> Javascript >> Objective-C
(根据某些竞争条件,这里可能会崩溃)
解决scheme是特定于您的项目代码。 但最简单的方法是将所有的Javascript包装在setTimeout()
以便在Javascript线程中调度执行。 这里是一个简单的例子,你的Objective-C代码需要执行这个脚本:
storeUserPhoneNumber("011 123 4567");
如果storeUserPhoneNumber
函数在其主体中直接或间接调用Objective-C代码,则会发生崩溃。 要解决这个只是在setTimeout中包装代码,像这样:
setTimeout(function() { storeUserPhoneNumber("011 123 4567"); }, 0);