开发iOS应用,解决Crash问题始终是一个难题。Crash分为两种,一种是由EXC_BAD_ACCESS引起的,原因是访问了不属于本进程的内存地址,有可能是访问已被释放的内存;另一种是未被捕获的Objective-C异常(NSException),导致程序向自身发送了SIGABRT信号而崩溃。其实对于未捕获的Objective-C异常,我们是有办法将它记录下来的,如果日志记录得当,能够解决绝大部分崩溃的问题。这里对于UI线程与后台线程分别说明。
以下代码内存越界会崩溃。
用分类的方式,重写NSArray的load方法。分类可以解耦,降低耦合度。我们的目标是高内聚,低耦合。
但是这样实用性不强。
最好是捕捉异常。
异常的捕捉
UMCrashTool,分析底层的dsym()文件,奔溃的行,文件,类。
UncaughtExceptionHandle
为了能够第一时间发现程序问题,应用程序需要实现自己的崩溃日志收集服务,成熟的开源项目很多,如 KSCrash,plcrashreporter,CrashKit 等。追求方便省心,对于保密性要求不高的程序来说,也可以选择各种一条龙Crash统计产品,如 Crashlytics,Hockeyapp ,友盟,Bugly 等等
要做到:捕获exception,处理,存储url,和上传。程序员再做线下的改代码。
将所有的runloop拷过来,相当于弄一个平行空间,使其继续运行,不至于全盘崩溃。原来奔溃的程序,终止,进入while的死循环。
埋点
除了收集和exception,signal,还需要统计和埋点。
埋点的目的主要是为了分析统计App使用的情况
一般埋点主要用于界面,action事件
界面中的数据一般都是静态的 和业务逻辑不相关, 一般是进入离开时间,是否进入该界面
action事件交互统计 ,一般是点击 双击 手势等交互
方案
1 使用第三方sdk: 例如:umeng统计 百度 腾讯MTA 等
2 手动埋点:常规的做法是将埋点代码封装成工具类,凡是工程中需要埋点(如点击事件、页面跳转)的地方都应用埋点代码。
a)主要统计的数据为:当前页面,页面停留时间(进入与离开时间差计算),点击事件等。缺点是代码散乱不易维护
b)记录每个页面进入退出(viewWillAppear与viewWillDisappear)的时间,用来计算页面停留时间,把触发时间以及一些点击行为操作全记到一个模型对象中,然后在页面离开或点击事件触发把这个模型写入到数据表中,到时候只要从表中取出数据再发送给后台即可实现埋点。
c)为防止对后台接口造成数据攻击,每5分钟从数据库中取一次数据发送,每200条列表数据向服务发送,直到本次取出所有数据全部发送完毕.
3.无码埋点
Method Swizzling、Hook与代码注入,基于运行时的埋点方案
唯一标识问题
唯一标识的组成方式主要是又 target + action 来确定, 即任何一个事件都存在一个target与action。 在此引入AOP编程,AOP(Aspect-Oriented-Programming)即面向切面编程的思想,基于 Runtime 的 Method Swizzling能力,来 hook 相应的方法,从而在hook方法中进行统一的埋点处理。例如所有的按钮被点击时,都会触发UIApplication的sendAction方法,我们hook这个方法,即可拦截所有按钮的点击事件。