前段时间发现bugly上有上报下面这个异常,而且这种情况只出现在ios 12上
异常错误堆栈信息 报错的设备和系统版本号-[CAGradientLayer _clearContents]: unrecognized selector sent to instance
就去网上搜了下这种报错信息,发现好多人说是项目里面有给CAGradientLayer这个类添加了类别,覆盖了系统的+layerClass方法,我就在项目里找,没找到给CAGradientLayer 添加类别的地方。
继续搜索,发现苹果开发者论坛上也有人提问这个问题,但是没解决方案。
https://developer.apple.com/forums/thread/115792?answerId=358276022#358276022
我想既然是方法找不到报错了, 那就可以拦截报错方法处理就好了,说干就干。
我就利用OC的RunTime特性,在CAGradientLayer找不到clearContents这个方法的时候把这个事件交给另一个处理异常的类去处理掉,完整代码如下:
CAGradientLayer+RM.h
@interface CAGradientLayer (RM)
@end
CAGradientLayer+RM.m
@interface HandleCrashClass : NSObject
@end
@implementation HandleCrashClass
@end
//处理未找到方法的时候闪退的
@implementation CAGradientLayer (RM)
- (BOOL)resolveClassMethod:(SEL)sel {
return NO;
}
/** 未找到方法的时候在这里返回有实现该方法的实例*/
- (id)forwardingTargetForSelector:(SEL)aSelector {
return nil;
}
/** 没有返回找到要实现的实例的时候在这里处理*/
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
class_addMethod([HandleCrashClassclass], aSelector, (IMP)missSel,"v@:@");
return [[HandleCrashClass new] methodSignatureForSelector:aSelector];
}
-(void)forwardInvocation:(NSInvocation*)anInvocation {
[anInvocationinvokeWithTarget:[HandleCrashClassnew]];
}
/** 未找到要执行的方法的时候就会到这里*/
- (void)doesNotRecognizeSelector:(SEL)aSelector {}
void missSel() {}
@end
上线后发现这种错误后面就再也没报了,这个闪退问题就算解决了。
网友评论