iOS - 消息转发处理

时间:2022-09-30 20:51:14

高效编写代码-消息转发

深入了解runtime

NSInvocation介绍

NSHipster-Swizzling

Objective-C Method相关方法分析

Type Encodings

推荐阅读高效编写代码-消息转发

在这里,我只针对一个经常出现的Crash给出利用消息转发处理的方案。

应用:处理Crash : unrecognized selector send to instance

@implementation NSObject (Swizzling)

+ (BOOL)lv_swizzlingInstanceOringnalSel:(SEL)orignalSel AletSel:(SEL)aletSel {

    if (!orignalSel || !aletSel) {
return NO;
} Class cls = [self class]; Method orignalMethod = class_getInstanceMethod(cls, orignalSel);
Method aletMethod = class_getInstanceMethod(cls, aletSel); BOOL addAletMethod = class_addMethod(cls, aletSel,
method_getImplementation(aletMethod),
method_getTypeEncoding(aletMethod));
if (addAletMethod) {
class_replaceMethod(cls, aletSel,
method_getImplementation(orignalMethod),
method_getTypeEncoding(orignalMethod));
}else {
method_exchangeImplementations(orignalMethod, aletMethod);
}
return YES;
} + (BOOL)lv_swizzlingClassOrignalSel:(SEL)orignalSel AletSel:(SEL)aletSel {
return [object_getClass((id)self) lv_swizzlingInstanceOringnalSel:orignalSel AletSel:aletSel];
} @end @implementation NSNull (NilSafe) + (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self lv_swizzlingInstanceOringnalSel:@selector(methodSignatureForSelector:) AletSel:@selector(lv_methodSignatureForSelector:)];
[self lv_swizzlingInstanceOringnalSel:@selector(forwardInvocation:) AletSel:@selector(lv_forwardInvocation:)];
});
} - (NSMethodSignature *)lv_methodSignatureForSelector:(SEL)aSelector {
NSMethodSignature * sign = [self lv_methodSignatureForSelector:aSelector];
if (sign) {
return sign;
}
return [NSMethodSignature signatureWithObjCTypes:@encode(void)];
} - (void)lv_forwardInvocation:(NSInvocation *)anInvocation {
return;
} @end