消息转发调用
对象 p p对象方法Method_list中没有相关方法时 的消息查找 步骤
1.动态方法解析--添加方法实现 (注意:这个方法会调用多次 最好不要用在消息转发)
对象方法
+ (BOOL)resolveInstanceMethod:(SEL)sel{
NSString*method =NSStringFromSelector(sel);
if([methodisEqualToString:@"sendMessage:"]) {
return class_addMethod(self, sel, (IMP)sendIMP,"V@:@");
}
return NO;
}
voidsendIMP(idself,SEL_cmd,NSString*msg){
NSLog(@"msg = %@",msg);
}
类方法
+(BOOL)resolveClassMethod:(SEL)sel{
NSString*method =NSStringFromSelector(sel);
if([methodisEqualToString:@"testMessage"]) {
// NSString *className = NSStringFromClass([animal class]);
// id is = objc_getClass([className UTF8String]);
return class_addMethod(object_getClass([animal class]), sel, (IMP)sendf, "V@:");
}
returnNO;
}
void sendf(id self,SEL _cmd){
NSLog(@"messgae");
}
2.快速转发
对象方法
- (id)forwardingTargetForSelector:(SEL)aSelector{
NSString*method =NSStringFromSelector(aSelector);
if([methodisEqualToString:@"testMessage"]) {
return[Personnew];
}
return [super forwardingTargetForSelector:aSelector];
}
类方法
+ (id)forwardingTargetForSelector:(SEL)aSelector{
NSString*method =NSStringFromSelector(aSelector);
if([methodisEqualToString:@"testMessage"]) {
return[Personclass];
}
return [super forwardingTargetForSelector:aSelector];
}
3.正常消息转发(慢速转发)
//先签名方法 动态绑定sel(方法名称指针)-> IMP(方法实现指针)
- (NSMethodSignature*)methodSignatureForSelector:(SEL)aSelector{
NSString*method =NSStringFromSelector(aSelector);
if([methodisEqualToString:@"sendMessage:"]) {
return [NSMethodSignature signatureWithObjCTypes:"V@:@"];
}
return [super methodSignatureForSelector:aSelector];
}
//
- (void)forwardInvocation:(NSInvocation*)anInvocation{
SELsel = [anInvocationselector];
Person*p = [Personnew];
if ([p respondsToSelector:sel]) {
[anInvocationinvokeWithTarget:p];
}else{
[superforwardInvocation:anInvocation];
}
}
4.////未找到方法
- (void)doesNotRecognizeSelector:(SEL)aSelector{
NSLog(@"no selector");
}
5,消息转发直接调用 方法签名的
Person *p =[[Person alloc]init];
NSMethodSignature*methodSign = [pmethodSignatureForSelector:@selector(sendMessage:)];
NSInvocation*invocation = [NSInvocationinvocationWithMethodSignature:methodSign];
invocation.target= p;
invocation.selector=@selector(sendMessage:);
NSString *str = @"invocation";
[invocationsetArgument:&stratIndex:2];2——表示sendMessage:方法的第3个参数
[invocationinvoke];