iOS 消息转发机制
名词描述
消息转发机制: 在iOS 中,当用户向某个类发送消息,即调用objc_msgSend
时 ,所接受的类不具备该方法,按照runtime
的机制,则会向该类的父类传递该方法,直到NSObject
类。
调用方法
试用场景
上述的消息转发机制是在runtime
内部中实现的,那我们要自己实现这种操作需要怎么完成呢?iOS
也提供了相关的API,即NSInvocation
。另外,在我实际的实践编码中,我将该api用于架构解耦。
因为架构解耦的场景一般是在比较大型的项目中,且项目逻辑且已经较为完善的情况下才进行的,当中间层的模块想要调用上层类的方法时,我们可以用到NSInvocation
来进行消息转发,因为调用的是系统底层的api,在效率上是很高的。如果使用通知,那代码的可读性就变得没有那么好。
调用实例方法
在进行方法调用的时候我们需要先指定目标类、目标方法。
// 1.获取到目标类
Class class = NSClassFromString(@"Test");
// 2.获取到目标SEL 方法
SEL sel = NSSelectorFromString(@"testMethod");
// 3.实例化该类
NSObject *obj = [class new];
// 4.获取到该类的目标方法签名
NSMethodSignature *methodSign = [obj methodSignatureForSelector:sel];
// 5.创建invocation对象
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSign];
// 6.指定该invocation 的调用对象
[invocation setTarget:obj];
// 7.指定该invocation 的调用方法
[invocation setSelector:sel];
// 8.执行该invocation
[invocation invoke];
调用类方法
调用类方法和实例方法之间的差距就是 invocation
方法签名和invocation
的调用对象。
// 1.获取到目标类
Class class = NSClassFromString(@"Test");
// 2.获取到目标SEL 方法
SEL sel = NSSelectorFromString(@"addMethod");
// 3.获取到该类的目标方法签名
NSMethodSignature *methodSign = [class methodSignatureForSelector:sel];
// 4.创建invocation对象
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSign];
// 5.指定该invocation 的调用对象
[invocation setTarget:class];
// 6.指定该invocation 的调用方法
[invocation setSelector:sel];
// 7.执行该invocation
[invocation invoke];
差异性总结
方法 | Target | NSMethodSignature |
---|---|---|
类方法 | Class 类 | 使用Class类和SEL去创建签名 |
实例方法 | Class 类的实例 | 使用Class类的实例和SEL去创建签名 |