此防护系统并不能解决所有的崩溃类型,只是对一些高频crash进行一一的处理,我们的目的就是降低crash率。
这套防护系统被命名为:『CrashKiller(闪退杀手)』,名字缘起于电影《杀死比尔》。
不过呢,这不重要。。。我就是为这个项目起了个花里胡哨的名字,并给这个名字赋予了一些无聊的意义。。。
通过CocoaPods方式安装CrashKiller ,请在Podfile 中指定:
//安装最新的tag版本
pod 'CrashKiller'
typedef NS_OPTIONS(NSUInteger, CrashKillerDefendCrashType) {
CrashKillerDefendUnrecognizedSelector = 1 << 1,
CrashKillerDefendKVC = 1 << 2,
CrashKillerDefendKVO = 1 << 3,
CrashKillerDefendNSTimer = 1 << 4,
CrashKillerDefendDictionaryContainer = 1 << 5,
CrashKillerDefendArrayContainer = 1 << 6,
CrashKillerDefendStringContainer = 1 << 7,
CrashKillerDefendSetContainer = 1 << 8,
CrashKillerDefendJSONSerialization = 1 << 9,
CrashKillerDefendNSFileManager = 1 << 10,
CrashKillerDefendNSFileHandle = 1 << 11,
CrashKillerDefendDataContainer = 1 << 12,
CrashKillerDefendAll = CrashKillerDefendUnrecognizedSelector | CrashKillerDefendKVC | CrashKillerDefendKVO | CrashKillerDefendNSTimer | CrashKillerDefendDictionaryContainer | CrashKillerDefendArrayContainer | CrashKillerDefendStringContainer | CrashKillerDefendSetContainer | CrashKillerDefendJSONSerialization | CrashKillerDefendNSFileManager | CrashKillerDefendNSFileHandle | CrashKillerDefendDataContainer
};[CrashKiller configDefendCrashType:CrashKillerDefendUnrecognizedSelector | CrashKillerDefendKVC];
[CrashKiller start];//如果terminateWhenException设置为YES,发生异常时将终止应用程序
//如果terminateWhenException设置为NO,则该异常只显示在控制台上,不会停止应用程序
//默认NO
CrashKiller.terminateWhenException = YES;//YES:打印日志 NO:不打印日志;默认YES
CrashKiller.debugLog = NO;/*
类名白名单
白名单里的类中方法不做处理,相当于这个类关闭了CrashKillerDefendUnrecognizedSelector防护功能
[CrashKiller addSelectorClassWhiteList:@[NSClassFromString(@"MAUserLocation")]];
*/
+ (void)addSelectorClassWhiteList:(NSArray*)objects;[CrashKiller handleCrashLog:(id<CrashKillerLogDelegate>)self];
- (void)onLog:(NSException *)exception
{
NSLog(@"%@\n *** First throw call stack:%@",exception.reason,exception.callStackSymbols);
}- Unrecognized Selector(找不到对象方法或者类方法的实现)
- KVO Crash
- KVO 添加次数和移除次数不匹配:
- 移除未注册的观察者,导致崩溃
- 重复移除多次,移除次数多于添加次数,导致崩溃
- 重复添加多次,虽然不会崩溃,但是发生改变时,也同时会被观察多次
- 被观察者提前被释放,被观察者在 dealloc 时仍然注册着 KVO,导致崩溃。 例如:被观察者是局部变量的情况(iOS 10 及之前会崩溃)。
- 添加了观察者,但未实现 observeValueForKeyPath:ofObject:change:context: 方法,导致崩溃。
- 添加或者移除时 keypath == nil,导致崩溃。
- KVO 添加次数和移除次数不匹配:
- KVC Crash
- key 不是对象的属性,造成崩溃。
- keyPath 不正确,造成崩溃。
- key 为 nil,造成崩溃。
- value 为 nil,为非对象设值,造成崩溃。
- NSTimer
- 注册了没有主动释放,会导致内存泄露,多线程中有可能会闪退
- 注册了没有主动释放,会导致内存泄露,多线程中有可能会闪退
- NSNull
- null类型调用其他类型(如NSString,NSNumber)方法,找不到方法
- null类型调用其他类型(如NSString,NSNumber)方法,找不到方法
- NSArray,NSMutableArray,NSDictonary,NSMutableDictionary,NSString,NSMutableString,NSSet,NSMutableSet,NSJSONSerialization,NSFileManager,NSFileHandle,NSData
- 数组越界,参数为nil等
CrashKiller is available under the MIT license. See the LICENSE file for more info.