查看bugly,好多崩潰由于莫名原因數(shù)組越界或者取超出數(shù)組范圍內(nèi)容,亦或set nil for ?key 了,針對(duì)這些增加幾個(gè)category來(lái)避免直接崩的情況,提升用戶體驗(yàn)。
一、NSArray:
創(chuàng)建NSArray的擴(kuò)展類,NSArray+Extension。重寫load方法,通過runtime 交換方法來(lái)實(shí)現(xiàn)。
+(void)load
{
? ? staticdispatch_once_tonceToken;
? ? dispatch_once(&onceToken, ^{
? ? ? ? // objectindex
? ? ? ? MethodoldObjectAtIndex =class_getInstanceMethod(objc_getClass("__NSArrayI"),@selector(objectAtIndex:));
? ? ? ? MethodnewObjectAtIndex =class_getInstanceMethod(objc_getClass("__NSArrayI"),@selector(objectAtSafeIndex:));
? ? ? ? method_exchangeImplementations(oldObjectAtIndex, newObjectAtIndex);
? ? ? ? // arr[4]
? ? ? ? MethodoldObjectAtIndex1 =class_getInstanceMethod(objc_getClass("__NSArrayI"),@selector(objectAtIndexedSubscript:));
? ? ? ? MethodnewObjectAtIndex1 =? class_getInstanceMethod(objc_getClass("__NSArrayI"),@selector(safeobjectAtIndexedSubscript:));
? ? ? ? method_exchangeImplementations(oldObjectAtIndex1, newObjectAtIndex1);
? ? });
}
因?yàn)?,?shù)組取值可以用objectindex 和 arr[index]兩種方式,所以需要這兩種方法都需要替換。
- (id)objectAtSafeIndex:(NSUInteger)index
{
? ? if(index >self.count-1|| !self.count) {
? ? ? ? @try{
? ? ? ? ? ? return[selfobjectAtSafeIndex:index];
? ? ? ? }
? ? ? ? @catch(NSException *exception) {
? ? ? ? ? ? NSLog(@"exception: %@", exception.reason);
? ? ? ? ? ? returnnil;
? ? ? ? }
? ? }else{
? ? ? ? return[selfobjectAtSafeIndex:index];
? ? }
}
- (instancetype)safeobjectAtIndexedSubscript:(NSUInteger)index{
? ? if(index > (self.count-1)) {// 數(shù)組越界
? ? ? ? returnnil;
? ? }else{// 沒有越界
? ? ? ? return [self safeobjectAtIndexedSubscript:index];
? ? }
}
二、NSMutableArray+Extension。。。同理,可變數(shù)組如下:
+(void)load? //第一次加載內(nèi)存的時(shí)候會(huì)自動(dòng)調(diào)用。
{
? ? staticdispatch_once_tonceToken;
? ? dispatch_once(&onceToken, ^{
? ? ? ? //addObject
? ? ? ? MethodorginalMethod =class_getInstanceMethod(NSClassFromString(@"__NSArrayM"),@selector(addObject:));
? ? ? ? MethodnewMethod =class_getInstanceMethod(NSClassFromString(@"__NSArrayM"),@selector(gp_addobjc:));
? ? ? ? method_exchangeImplementations(orginalMethod, newMethod);
? ? ? ? //替換objectAtIndex方法
? ? ? ? MethodoldMutableObjectAtIndex =class_getInstanceMethod(objc_getClass("__NSArrayM"),@selector(objectAtIndex:));
? ? ? ? MethodnewMutableObjectAtIndex =? class_getInstanceMethod(objc_getClass("__NSArrayM"),@selector(mutableObjectAtSafeIndex:));
? ? ? ? method_exchangeImplementations(oldMutableObjectAtIndex, newMutableObjectAtIndex);
? ? ? ? //替換arr[4]方法
? ? ? ? MethodoldMutableObjectAtIndex1 =class_getInstanceMethod(objc_getClass("__NSArrayM"),@selector(objectAtIndexedSubscript:));
? ? ? ? MethodnewMutableObjectAtIndex1 =? class_getInstanceMethod(objc_getClass("__NSArrayM"),@selector(safeobjectAtIndexedSubscript:));
? ? ? ? method_exchangeImplementations(oldMutableObjectAtIndex1, newMutableObjectAtIndex1);
? ? });
}
//addobject
-(void)gp_addobjc:(id)object
{
? ? if(object !=nil) {
? ? ? ? [self gp_addobjc:object];//此時(shí)? 方法交換,所以不能在這寫addobject。若這樣的話,會(huì)造成死循環(huán)。
? ? }
}
//objectAtIndex
- (id)mutableObjectAtSafeIndex:(NSUInteger)index
{
? ? if(index >self.count-1|| !self.count) {
? ? ? ? @try{
? ? ? ? ? ? return [self mutableObjectAtSafeIndex:index];
? ? ? ? }
? ? ? ? @catch(NSException *exception) {
? ? ? ? ? ? NSLog(@"exception: %@", exception.reason);
? ? ? ? ? ? returnnil;
? ? ? ? }
? ? }else{
? ? ? ? return [self mutableObjectAtSafeIndex:index];
? ? }
}
//aar[index]
- (instancetype)safeobjectAtIndexedSubscript:(NSUInteger)index{
? ? if(index > (self.count-1)) {// 數(shù)組越界
? ? ? ? returnnil;
? ? }else{// 沒有越界
? ? ? ? return [self safeobjectAtIndexedSubscript:index];
? ? }
}