先提出疑问这个方法是怎么来的?
![]()

log_and_fill_cache jump 填充缓存
![]()
logMessageSend jump
![]()
instrumentObjcMessageSends jump
![]()
所以extern void instrumentObjcMessageSends(BOOL flag);就是将里面的方法,做了外部扩展,传值YES/NO
![]()
接下来在HLPerson.m文件中添加forwardingTargetForSelector方法 -- 快速转发
![]()
//输出
-[HLPerson forwardingTargetForSelector:] *** sayNB
-[HLPerson sayNB]: unrecognized selector sent to instance 0x100a72f70
修改返回值, HLTeacher 类有- (void)teacherSay方法 -- 快速转发

//快速转发
- (id) TargetForSelector:(SEL)aSelector{
NSLog(@"%s *** %@",__func__,NSStringFromSelector(aSelector));
return [HLTeacher alloc];
}
//输出
-[HLPerson forwardingTargetForSelector:] *** sayNB
-[HLTeacher teacherSay]
//慢速转发
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{
NSLog(@"%s --- %@",__func__,NSStringFromSelector(aSelector));
if (aSelector == @selector(sayNB)) {
return [NSMethodSignature signatureWithObjCTypes:"v@:"];
}
return [super methodSignatureForSelector:aSelector];
}
//输出
-[HLPerson methodSignatureForSelector:] --- sayNB
- (void)forwardInvocation:(NSInvocation *)anInvocation{
NSLog(@"%@ ### %@",anInvocation.target,NSStringFromSelector(anInvocation.selector));
}
-[HLPerson methodSignatureForSelector:] --- sayNB
<HLPerson: 0x101547e20> ### sayNB
Program ended with exit code: 0
//添加respondsToSelector判断
- (void)forwardInvocation:(NSInvocation *)anInvocation{
// NSLog(@"%@ ### %@",anInvocation.target,NSStringFromSelector(anInvocation.selector));
HLTeacher *t = [HLTeacher alloc];
if ([self respondsToSelector:anInvocation.selector]) {
[anInvocation invoke];
}else if ([t respondsToSelector:anInvocation.selector]){
[anInvocation invokeWithTarget:t];
}else{
NSLog(@"%s --- %@",__func__,NSStringFromSelector(anInvocation.selector));
[anInvocation invoke];
}
}
现在把上面的快速和慢速方法先注释,看下lldb
![]()
//报错的关键
frame #10: 0x00007fff2059b90b CoreFoundation`___forwarding___ + 1448
frame #11: 0x00007fff2059b2d8 CoreFoundation`_CF_forwarding_prep_0 + 120
未完待续...
网友评论