很多開發(fā)小伙伴們經(jīng)常私信問我一些問題:
1、若集成了騰訊Bugly或者友盟等等異常搜集的SDK,AvoidCrash會(huì)影響到它們的異常搜集嗎志膀?
2鳖擒、為什么集成了AvoidCrash還是會(huì)報(bào)unrecognized selector sent to instance的異常蒋荚?
疑惑1
1惊奇、若集成了騰訊Bugly或者友盟等等異常搜集的SDK,AvoidCrash會(huì)影響到它們的異常搜集嗎播赁?
首先要清楚的一點(diǎn)是容为,對(duì)于一些第三方crash信息搜集工具寺酪,比如Bugly或者友盟,它們只有當(dāng)程序出現(xiàn)異常(崩潰)的時(shí)候才會(huì)搜集異常信息替劈。而AvoidCrash的作用是寄雀,防止部分常見異常的發(fā)生,異常被AvoidCrash捕獲了陨献,程序就不會(huì)崩潰盒犹,第三方crash信息搜集工具就不會(huì)搜集到崩潰信息咯。
如何處理才能既防止崩潰眨业,又搜集到崩潰信息
AvoidCrash若捕獲到異常急膀,將會(huì)發(fā)出一個(gè)通知:AvoidCrashNotification,監(jiān)聽該通知即可獲取到原本將導(dǎo)致崩潰的具體信息。此時(shí)你可以利用Bugly的自定義異常接口將這些異常信息上傳到Bugly坛猪。下面上代碼脖阵,上圖說明。
1墅茉、首先先來查看下Bugly提供的上報(bào)異常的接口
Bugly上報(bào)自定義異常接口
2命黔、創(chuàng)建一個(gè)上報(bào)異常的工具類 BuglyManager(可以充分利用Bugly上報(bào)自定義異常功能,方便我們快速定位app出現(xiàn)的異常,下圖展示了我所開發(fā)的項(xiàng)目中使用Bugly上報(bào)了哪些錯(cuò)誤類型)
/** 上報(bào)錯(cuò)誤信息 */
+ (void)reportErrorName:(NSString *)errorName errorReason:(NSString *)errorReason callStack:(NSArray *)aStackArray extraInfo:(NSDictionary *)info{
[Bugly reportExceptionWithCategory:3 errorName reason:errorReason callStack:aStackArray extraInfo:info terminateApp:NO];
}
3就斤、在AppDelegate中初始化AvoidCrash并且監(jiān)聽通知:AvoidCrashNotification
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[AvoidCrash makeAllEffective];
//監(jiān)聽通知:AvoidCrashNotification, 獲取AvoidCrash捕獲的崩潰日志的詳細(xì)信息
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dealwithCrashMessage:) name:AvoidCrashNotification object:nil];
return YES;
}
- (void)dealwithCrashMessage:(NSNotification *)note {
//異常攔截并且通過bugly上報(bào)
NSDictionary *info = note.userInfo;
NSString *errorReason = [NSString stringWithFormat:@"【ErrorReason】%@========【ErrorPlace】%@========【DefaultToDo】%@========【ErrorName】%@", info[@"errorReason"], info[@"errorPlace"], info[@"defaultToDo"], info[@"errorName"]];
NSArray *callStack = info[@"callStackSymbols"];
[BuglyManager reportErrorName:Bugly_ErrorName_AvoidCrash errorReason:errorReason callStack:callStack extraInfo:nil];
4悍募、寫一個(gè)AvoidCrash可以攔截的異常
NSArray *array = @[@"iOS"];
NSString *string = array[100];
5、在Xcode控制臺(tái)可以看到下圖的輸出
6洋机、去Bugly錯(cuò)誤分析中查看
疑惑2
2坠宴、為什么集成了AvoidCrash還是會(huì)報(bào)unrecognized selector sent to instance的異常?
很多小伙伴并沒有下載過Demo查看AppDelegate中的代碼和注釋绷旗,其實(shí)在里面都寫得比較詳細(xì)了喜鼓,并且在AvoidCrash.h文件中的部分方法也寫了一些注意事項(xiàng)。
若要捕獲 unrecognized selector sent to instance 類型的異常
1衔肢、首先查看下AvoidCrash中初始化AvoidCrash的兩個(gè)方法
/**
*
* 開始生效.你可以在AppDelegate的didFinishLaunchingWithOptions方法中調(diào)用becomeEffective方法
* 【默認(rèn)不開啟 對(duì)”unrecognized selector sent to instance”防止崩潰的處理】
*
*/
+ (void)becomeEffective;
/**
* 相比于becomeEffective庄岖,增加
* 對(duì)”unrecognized selector sent to instance”防止崩潰的處理
*
* 但是必須配合setupClassStringsArr:使用
*/
+ (void)makeAllEffective;
2、若要捕獲 unrecognized selector sent to instance 類型的異常角骤,請(qǐng)使用[AvoidCrash makeAllEffective] 并且配合下面的兩個(gè)方法使用隅忿。(這兩個(gè)方法可以配合使用,可以同時(shí)使用)
/**
* 初始化一個(gè)需要防止”unrecognized selector sent to instance”的崩潰的類名數(shù)組
* ??不可將@"NSObject"加入classStrings數(shù)組中
* ??不可將UI前綴的字符串加入classStrings數(shù)組中
*/
+ (void)setupNoneSelClassStringsArr:(NSArray<NSString *> *)classStrings;
/**
* 初始化一個(gè)需要防止”unrecognized selector sent to instance”的崩潰的類名前綴的數(shù)組
* ??不可將UI前綴的字符串(包括@"UI")加入classStringPrefixs數(shù)組中
* ??不可將NS前綴的字符串(包括@"NS")加入classStringPrefixs數(shù)組中
*/
+ (void)setupNoneSelClassStringPrefixsArr:(NSArray<NSString *> *)classStringPrefixs;
3邦尊、具體的使用方法
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[AvoidCrash makeAllEffective];
//================================================
// 1背桐、unrecognized selector sent to instance(方式1)
//================================================
//若出現(xiàn)unrecognized selector sent to instance并且控制臺(tái)輸出:
//-[__NSCFConstantString initWithName:age:height:weight:]: unrecognized selector sent to instance
//你可以將@"__NSCFConstantString"添加到如下數(shù)組中,當(dāng)然蝉揍,你也可以將它的父類添加到下面數(shù)組中
//比如链峭,對(duì)于部分字符串,繼承關(guān)系如下
//__NSCFConstantString --> __NSCFString --> NSMutableString --> NSString
//你可以將上面四個(gè)類隨意一個(gè)添加到下面的數(shù)組中疑苫,建議直接填入 NSString
//我所開發(fā)的項(xiàng)目中所防止unrecognized selector sent to instance的類有下面幾個(gè)熏版,主要是防止后臺(tái)數(shù)據(jù)格式錯(cuò)亂導(dǎo)致的崩潰纷责。個(gè)人覺得若要防止后臺(tái)接口數(shù)據(jù)錯(cuò)亂,用下面的幾個(gè)類即可撼短。
NSArray *noneSelClassStrings = @[
@"NSNull",
@"NSNumber",
@"NSString",
@"NSDictionary",
@"NSArray"
];
[AvoidCrash setupNoneSelClassStringsArr:noneSelClassStrings];
//================================================
// 2再膳、unrecognized selector sent to instance(方式2)
//================================================
//若需要防止某個(gè)前綴的類的unrecognized selector sent to instance
//比如你所開發(fā)項(xiàng)目中使用的類的前綴:CC、DD
//你可以調(diào)用如下方法
NSArray *noneSelClassPrefix = @[
@"CC",
@"DD"
];
[AvoidCrash setupNoneSelClassStringPrefixsArr:noneSelClassPrefix];
//監(jiān)聽通知:AvoidCrashNotification, 獲取AvoidCrash捕獲的崩潰日志的詳細(xì)信息
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dealwithCrashMessage:) name:AvoidCrashNotification object:nil];
return YES;
}