實現原理基于runtime的方法交換和消息發(fā)送機制
方法交換 method_exchangeImplementations?
NSObject添加分類
@implementation NSObject (Forwarding)
static ForwardingTarget *target;
+ (void)load{
? ? staticdispatch_once_tonceToken;
? ? dispatch_once(&onceToken, ^{
? ? ? ? target = [ForwardingTarget new];
? ? ? ? MethodoriginalMethod =class_getInstanceMethod([selfclass],@selector(forwardingTargetForSelector:));
? ? ? ? MethodswizzlingMethod =class_getInstanceMethod([selfclass],@selector(customForwardingTargetForSelector:));
? ? ? ? BOOL didAdd = class_addMethod([self class],method_getName(originalMethod) ,method_getImplementation(originalMethod) , method_getTypeEncoding(originalMethod));
? ? ? ? if(didAdd) {
? ? ? ? ? ? class_replaceMethod([self class], method_getName(originalMethod), method_getImplementation(swizzlingMethod), method_getTypeEncoding(swizzlingMethod));
? ? ? ? }else{
? ? ? ? ? ? method_exchangeImplementations(originalMethod, swizzlingMethod);
? ? ? ? }
? ? });
}
-(id)customForwardingTargetForSelector:(SEL)aSelector{
? ? id result = [self customForwardingTargetForSelector:aSelector];
? ? if(result)returnresult;
? ? returntarget;
}
這個類里主要是交換了系統的forwardingTargetForSelector:方法,轉發(fā)給ForwardingTarget這個類唇礁,而ForwardingTarget類里重寫resolveInstanceMethod柜去,動態(tài)添加方法
@implementation ForwardingTarget
id newDynamicMethod(id self, SEL _cmd){
? ? return[NSNullnull];
}
+(BOOL)resolveInstanceMethod:(SEL)sel{
? ? class_addMethod([selfclass], sel, (IMP)newDynamicMethod,"@@:");
? ? [super resolveInstanceMethod:sel];
? ? return YES;
}
@end