今天的博客来一波消息转发,可能最后会涉及到反汇编
(兄弟们不要慌{刚开始我是最慌的😆},我们不需要全看懂他,我们只需要了解大致流程就行)
1. 代码分析
-
- 先搞一波,方法没有实现的代码
@interface XGTest : NSObject
- (void)testDemo;
@end
@implementation XGTest
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
XGTest *test = [XGTest alloc];
[test testDemo];
NSLog(@"Hello, World!");
}
return 0;
}
我们都知道的一件事情:它会崩~(不知道就运行下😆)
1.1. instrumentObjcMessageSends辅助分析
兄弟们先容我开一波上帝视角~(最后我会用反汇编证明)
-
- 上代码:
extern void instrumentObjcMessageSends(BOOL flag);
instrumentObjcMessageSends(YES);
[test testDemo];
instrumentObjcMessageSends(NO);
-
- 在调用方法前后加上
instrumentObjcMessageSends
,运行后在文件夹\tmp\
下会产生一个msgSends-
开头的文件
- 在调用方法前后加上
-
- 我们打开看下这个文件(log)
我们看出在动态方法决议之后,有走了一些方法~,但是我们不知道这个是啥?(其实就是快速转发和慢速转发~)
1.2. forwardingTargetForSelector分析
-
- 这个时候我们想到的是看下Apple 官方文档
-
- 点进去之后
哈哈,这个时候,我就要推荐个东西了 所以么,英文也是可以搞定的😆。。
-
- 这个意思就是你可以
找个接盘侠
(看来有道词典也不人性化)
- 这个意思就是你可以
-
- 那我创建一个新的
Class
,让他去替他实现,看看可否
- 那我创建一个新的
@interface XGSubTest : NSObject
- (void)testDemo;
@end
@implementation XGSubTest
- (void)testDemo{
NSLog(@"%s",__func__);
}
@end
@implementation XGTest
- (id)forwardingTargetForSelector:(SEL)aSelector{
NSLog(@"%s - %@",__func__,NSStringFromSelector(aSelector));
return [XGSubTest alloc];
// return [super forwardingTargetForSelector:aSelector];
}
@end
-
- 看下输出
确实不崩溃了~
1.3. methodSignatureForSelector
我们刚才看到,走完快速查找之后也走了这个方法,我们继续可以通过苹果文档来找答案~(探索过程中其实有我们好多不知道的东西、我们只能通过文档、源码、反汇编去猜)
-
- 点进去
-
- 这个仔细看的话会发现一个关联方法
这次
有道
的翻译还行😆
那我们这次就不在
forwardingTargetForSelector
中处理了~,看看methodSignatureForSelector
是否搞得定
-
- 我们要先看下文档里面说的返回值~
-
- 代码
@implementation XGTest
- (id)forwardingTargetForSelector:(SEL)aSelector{
NSLog(@"%s - %@",__func__,NSStringFromSelector(aSelector));
return [super forwardingTargetForSelector:aSelector];
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{
NSLog(@"%s - %@",__func__,NSStringFromSelector(aSelector));
return [NSMethodSignature signatureWithObjCTypes:"v@:"];
}
- (void)forwardInvocation:(NSInvocation *)anInvocation{
NSLog(@"%s - %@",__func__,anInvocation);
}
@end
-
- 他的确走了,而且没有崩溃,不过有点美中不足~(看下输出)
-
- 嘿咻~,那我就要试试,是不是可以指定方法处理~
这
终于完美了这个感觉可以做好多事。runtime
还是很强大~
2. 汇编验证
刚开始我们是开的上帝视角找到的
forwardingTargetForSelector
和methodSignatureForSelector
-
- 我们用反汇编验证下~:回到刚开始的状态,让他崩溃、然后看堆栈
-
- 我点击一下就可以看到~
-
- 我们第一反应就是找
CoreFoundation
的源码。。(这里我找过了。。找不到~)
- 我们第一反应就是找
-
- 那我们只能通过反汇编了~这里介绍个工具
可以找破解版。
-
- 我们找到编译的镜像文件(
image list
)
- 我们找到编译的镜像文件(
-
- 把他找到
拖进Hopper
- 把他找到
-
- 然后我们找到要观察的东西(全局搜索就可以定位到)
说实话,兄弟们
这个东西不好截图
-
- 下面我就给兄弟们贴出必要的东西吧
-
- 这个时候我们还不能确定他走了
methodSignatureForSelector
,那我们看他goto
之后走的流程~
- 这个时候我们还不能确定他走了
-
- 这样我们也会知道,走完动态方法协议会走
快速转发
和慢速转发
- 这样我们也会知道,走完动态方法协议会走
兄弟们~,画的有点乱凑合凑合😆