上一篇介紹了Method Swizzling
的相關(guān)方法,也介紹了一些常用場(chǎng)景酝蜒,今天就詳細(xì)介紹一下如何使用Method Swizzling
來(lái)攔截系統(tǒng)常見(jiàn)崩潰誊辉,感受Method Swizzling
帶來(lái)的真正魅力。
要攔截系統(tǒng)常見(jiàn)的崩潰亡脑,諸如數(shù)組越界堕澄,截取子串,插入空值等霉咨,就要先交換系統(tǒng)的方法蛙紫,再去攔截系統(tǒng)拋出的異常信息,舉個(gè)??途戒,現(xiàn)在要截取數(shù)組越界的崩潰坑傅,看代碼:
NSArray *array = @[@"1",@"2",@"3"];
NSLog(@"%@", array[3]);
正常情況下,這段代碼是肯定會(huì)崩潰的喷斋,看控制臺(tái)輸出的崩潰信息:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndexedSubscript:]: index 3 beyond bounds [0 .. 2]'
現(xiàn)在我們要攔截這個(gè)崩潰唁毒,首先在調(diào)用objectAtIndexdSubscript
方法之前(我們調(diào)用array[3]
本質(zhì)上就是調(diào)用objectAtIndexdSubscript
),我們要先交換這個(gè)方法继准,看代碼:
+ (void)ht_interceptArrayCrashCausedByIndexBeyondBounds {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class clsI = NSClassFromString(@"__NSArrayI");
[HTCrashReporter ht_swizzleInstanceMethodForClass:clsI
originalSelector:@selector(objectAtIndexedSubscript:)
swizzlingSelector:@selector(ht_objectAtIndexedSubscriptI:)];
});
}
- (id)ht_objectAtIndexedSubscriptI:(NSUInteger)idx {
id object = nil;
@try {
object = [self ht_objectAtIndexedSubscriptI:idx];
} @catch (NSException *exception) {
[HTCrashReporter ht_catchException:exception withCrashType:HTCrashTypeArrayIndexBeyondBounds];
} @finally {
return object;
}
}
這里有幾點(diǎn)需要注意下:
- 第一點(diǎn):交換方法需要寫(xiě)在+load方法里枉证,而且要保證只調(diào)用一次(這里不贅述具體原因,有興趣的小伙伴自行查找)移必;
- 第二點(diǎn):我們交換的是對(duì)象方法室谚,所以應(yīng)該調(diào)用
swizzleInstanceMethod
方法而不是swizzleClassMethod
方法; - 第三點(diǎn):??中的數(shù)組是不可變數(shù)組崔泵,根據(jù)控制臺(tái)輸出信息中提示的是
__NSArrayI
(兩道下劃線)秒赤,所以我們要替換的類是NSClassFromString(@"__NSArrayI")
; - 第四點(diǎn):有的小伙伴可能會(huì)有疑問(wèn)憎瘸,為什么在交換的方法里還要調(diào)用當(dāng)前方法入篮,這不就死循環(huán)了嗎?非也幌甘,這里看上去調(diào)用當(dāng)前方法潮售,但是實(shí)質(zhì)上內(nèi)部方法的實(shí)現(xiàn)是系統(tǒng)方法的實(shí)現(xiàn),所以這里使用了
try catch
語(yǔ)句锅风,因?yàn)閿?shù)組越界酥诽,系統(tǒng)方法會(huì)拋出異常,這里捕獲異常再做進(jìn)一步處理皱埠,比如上傳服務(wù)器肮帐。到這里就實(shí)現(xiàn)了攔截了數(shù)據(jù)越界引起的崩潰,程序不會(huì)閃退還是可以正常運(yùn)行。
上面只是一個(gè)簡(jiǎn)單的??训枢,HTCrashReporter做了NSString
,NSArray
,NSDictionary
,NSObject
常見(jiàn)崩潰攔截托修,歡迎各位大佬指正,不介意動(dòng)動(dòng)手指請(qǐng)賞個(gè)Star恒界。