美文网首页iOS开发
记一次Crash分析

记一次Crash分析

作者: Plokmijn | 来源:发表于2017-10-15 19:08 被阅读687次

在这里主要分析使用UIWebView导致产生crash的原因。

从我们项目的crash日志收集平台中,有诸多如下的日志:

Application received signal 11  

1   libobjc.A.dylib 0x1800bc150 _objc_msgSend + 16
2   UIKit           0x18799156c -[UIWebView webView:resource:didFinishLoadingFromDataSource:] + 84
3   CoreFoundation  0x18164ce80 ___invoking___ + 144
4   CoreFoundation  0x1815422c4 -[NSInvocation invoke] + 292
5   CoreFoundation  0x181546e9c -[NSInvocation invokeWithTarget:] + 60
6   WebKitLegacy    0x1873d4820 <redacted>

Application received signal 11

崩溃线程
WebThread
格式化
1   libobjc.A.dylib 0x1800bc150 _objc_msgSend + 16
2   UIKit           0x187c33354 -[UIWebView webThreadWebView:resource:willSendRequest:redirectResponse:fromDataSource:] + 92
3   WebKitLegacy    0x187477e60 <redacted>
4   WebKitLegacy    0x1873d315c <redacted>
5   WebCore         0x1861cdee0 WebCore::ResourceLoadNotifier::dispatchWillSendRequest(WebCore::DocumentLoader*, unsigned long, WebCore::ResourceRequest&, WebCore::ResourceResponse const&) + 232
6   WebCore         0x186f1c494 WebCore::ResourceLoader::willSendRequestInternal(WebCore::ResourceRequest&, WebCore::ResourceResponse const&) + 556
7   WebCore         0x18703cbb0 WebCore::SubresourceLoader::willSendRequestInternal(WebCore::ResourceRequest&, WebCore::ResourceResponse const&) + 252
8   WebCore         0x1861cd040 WebCore::ResourceLoader::init(WebCore::ResourceRequest const&) + 288
9   WebCore         0x1861ccdec WebCore::SubresourceLoader::startLoading() + 36
10  WebKitLegacy    0x1874b23b0 <redacted>

以前在看到这种日志的时候,就在想,signal 11崩溃日志不明确,或者说WebView的系统代码,不是我们自己的代码改不了的种种。。。

不过现在从crash统计平台的数据看来数量相当大,是非常影响用户的体验的。所以今天就抽时间来分析分析其原因。

从日志上看,基本都是Application received signal 11,那么signal 11是代表什么呢?

于是翻看系统的头文件sys/signal.h, 我们可以发现里面有一个宏定义#define SIGSEGV 11 /* segmentation violation */, 这个SIGSEGV其实就是signal 11的宏定义,注释很明确了:无效的内存引用

那么问题就来了,WebCore内部发出无效内存引用,我们好像也无能为力啊???咋办呢?

这时候就去看看UIWebView有没有其它什么可能的原因,发现在头delegate的定义
@property (nullable, nonatomic, assign) id <UIWebViewDelegate> delegate;
我们都知道assign一般是用于元类型,delegate在ARC下一般是被声明为weak

这就奇怪了,怎么这么声明呢? 因此带着疑问去看UIWebView的文档:

Protocol
UIWebViewDelegate
The UIWebViewDelegate protocol defines methods that a delegate of a 
UIWebView
 object can optionally implement to intervene when web content is loaded.
SDK

iOS 2.0+
Framework

UIKit
On This Page

Overview
Topics
Relationships
See Also
Overview

> Important
> Before releasing an instance of UIWebView for which you have set a delegate,
> you must first set the UIWebView delegate property to nil before disposing of the UIWebView instance. 
> This can be done, for example, in the dealloc method where you dispose of the UIWebView.`
>

意思就是: 在释放一个你已经为其设过 delegate 的 UIWebView 实例之前,你首先一定要将该 UIWebView 对象的 delegate 属性设为 nil。比如说,你可以在你的 dealloc 方法中这样做。

这时候就恍然大悟了,我们的项目中对WebView的使用并没有如此!!! 因为在UIWebView的delgate属性为assign 在被销毁的时候delegate不会被设为nil,导致WebView回调的时候引用的delegate已经是无效的内存指针了,因为指针指向的内存已经被释放,但指针没有被置空,这也正是文档里面为什么要重要强调需要在销毁前设置为nil的原因。

这也解释了为什么crash日志中总是收到莫名的WebView的crash,而且都是Application received signal 11(即无效的内存引用

到这里,相信大家都应该知道什么原因了,修改 UIWebView 的 delegate 的对象的 dealloc 方法中添加 _webView.delegate = nil; 如下:

- (void)dealloc{
    /*
     Important
     Before releasing an instance of UIWebView for which you have set a delegate,
     you must first set the UIWebView delegate property to nil before disposing of the UIWebView instance. 
     This can be done, for example, in the dealloc method where you dispose of the UIWebView.
     */
    if (self.webView.loading) {
        [self.webView stopLoading];
    }
    self.webView.delegate = nil;
}

ps:由于很少写文章,所以写出来的都是没深度没难度的流水帐。这里也就记录一下这个过程,以便以后遇到类似问题能够有不至于无从下手。如有错误,望看官们不吝指正。万分感激!

相关文章

  • 记一次Crash分析

    在这里主要分析使用UIWebView导致产生crash的原因。 从我们项目的crash日志收集平台中,有诸多如下的...

  • 记一次Crash分析

    在这里主要分析使用UIWebView导致产生crash的原因。 从我们项目的crash日志收集平台中,有诸多如下的...

  • crash 收集分析

    crash 收集分析 当app发生crash时会产生crash report,查看crash记录对我们定位cras...

  • 3.Xcode方面问题

    1.iOS崩溃日志分析 iOS 获得crash dSYM方法(手机本地连接方式) [iOS Crash文件分析]-...

  • 快速集成Bugly Android SDK

    腾讯Bugly,面向移动开发者提供最专业的Crash监控、崩溃分析等质量跟踪服务,为您修复用户的每一次Crash!...

  • atos,mac和ios的crash调用栈查看工具

    比如Mac上的Crash 分析Log 从上面的crash log看,程序crash在了线程CaptureThrea...

  • iOS crash分析

    Crash分析总结:主要分析AppStore线上版本的crash bug1.登录开发者账号,iTunes conn...

  • 【iOS开发】Crash 文件解析

    一、Crash文件解析参考文章:iOS: Crash文件解析(一)分析iOS Crash文件:符号化iOS Cra...

  • iOS Crash 符号化与分析

    iOS Crash 符号化与分析 1.crash文件与dSYM文件的UUID crash文件的UUIDBinary...

  • Android Crash之Native Crash分析

    前言 上一篇给大家介绍了Android Crash中的Java Crash分析,我们可以知道Java Crash一...

网友评论

  • hypercode:我奇怪的是,以前怎么很少遇到这种崩溃,最近这种崩溃特别多,代码一样的
  • hypercode:非常好,虽然还没验证,但是思路很对

本文标题:记一次Crash分析

本文链接:https://www.haomeiwen.com/subject/iaicuxtx.html