先提出疑问这个方法是怎么来的?
- lookUpImpOrForward jump
- 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
复制代码
未完待续…
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END