Runtime消息动态解析与转发流程
先上图:
下面根据具体代码看这张图。
一、创建一个Person类,
Person.h
#import <Foundation/Foundation.h>@interface Person : NSObject-(void)sendMessage:(NSString *)message;@end
Person.m
#import "Person.h" #import <objc/runtime.h>@implementation Person@end
大家可以看到,Person类只声明了 sendMessage:方法,在.m文件里没有实现这个方法。
这时,如果在viewController中调用Person类的sendMessage方法,程序会发生崩溃。
#import "ViewController.h" #import "Person.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];[[[Person alloc]init] sendMessage:@"Hello"];}
结合上面的图片,我们说说消息处理的机制。
1.当我们调用的方法没有具体的实现时,会调用
+ (BOOL)resolveInstanceMethod:(SEL)sel;
+(BOOL)resolveInstanceMethod:(SEL)sel{NSString *methodName = NSStringFromSelector(sel);if ([methodName isEqualToString:@"sendMessage:"]) {//我们可以在这里添加方法的实现return class_addMethod(self, sel, (IMP)sendMessage, "v@:@");}return NO;}void sendMessage (id self, SEL _cmd, NSString *message){NSLog(@"message=%@",message); }
BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types):为类动态添加方法。如果有同名会返回NO,成功返回YES。
其中的参数types查询地址:(v:表示void, @:表示类型,等等)
2. 如果 resolveInstanceMethod:方法返回NO,调用
-(id)forwardingTargetForSelector:(SEL)aSelector;
这个方法是找备用者,比如:Animal类。
Animal.h
#import <Foundation/Foundation.h>@interface Animal : NSObject@end
Animal.m
#import "Animal.h"@implementation Animal-(void)sendMessage:(NSString *)message{NSLog(@"message=%@",message); }@end
Animal类没有声明sendMessage:方法,但在.m文件里有这个方法的实现,可以作为备用者。如下:
-(id)forwardingTargetForSelector:(SEL)aSelector{NSString *methodName = NSStringFromSelector(aSelector);if ([methodName isEqualToString:@"sendMessage:"]) {if ([[Animal new] respondsToSelector:aSelector]) {return [Animal new];}}return [super forwardingTargetForSelector:aSelector]; }
3. 如果 forwardingTargetForSelector:(SEL)aSelector返回 nil。
// 若前两种方法都不处理,则走这里 // 1)方法签名 -(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{NSString *methodName = NSStringFromSelector(aSelector);if ([methodName isEqualToString:@"sendMessage:"]) {return [NSMethodSignature signatureWithObjCTypes:"v@:@"];}return [super methodSignatureForSelector:aSelector]; } // 2) 签名后,消息转发,找备用者 -(void)forwardInvocation:(NSInvocation *)anInvocation{SEL selector = [anInvocation selector];Animal *animal = [Animal new];if ([animal respondsToSelector:selector]) {[anInvocation invokeWithTarget:animal];} else{[super forwardInvocation:anInvocation];} }
4.如果走到第3步,仍然不做处理,如下:
-(void)forwardInvocation:(NSInvocation *)anInvocation{[super forwardInvocation:anInvocation]; }
这时为了程序的健壮性,防止崩溃,可以用以下方法处理。
// 若前3方法都不处理,为了防止崩溃,可调用此方法 -(void)doesNotRecognizeSelector:(SEL)aSelector{NSString *methodName = NSStringFromSelector(aSelector);NSLog(@"找不到 %@ 这个方法的实现",methodName); }
附加源码
转载于:https://www.cnblogs.com/lfyDragon/p/9177710.html
Runtime消息动态解析与转发流程相关推荐
- runtime消息转发机制
Objective-C 扩展了 C 语言,并加入了面向对象特性和 Smalltalk 式的消息传递机制.而这个扩展的核心是一个用 C 和 编译语言 写的 Runtime 库.它是 Objective- ...
- 基于`IRIS`,动态解析`HL7`消息
文章目录 基于`IRIS`,动态解析`HL7`消息 什么是`HL7` `HL7` 版本 `HL7` 消息结构 段(`Segment`) 字段(`Field`) `HL7` 数据类型 在`IRIS`中查 ...
- iOS底层开发消息发送与转发流程
iOS底层开发消息转发流程 一,cache缓存读取流程分析 首先我们上一章已经了解到对应的cache_t的数据结构 _bucketsAndMaybeMask:指针类型,存放buckets的首地址 _m ...
- Protobuf动态解析那些事儿
2019独角兽企业重金招聘Python工程师标准>>> 需求背景 在接收到 protobuf 数据之后,如何自动创建具体的 Protobuf Message 对象,再做反序列化.&q ...
- 利用NAS免费部署动态解析实现内网穿透
想要从外网访问家中的NAS等设备,一般来说我们需要知道家中路由器的公网IP. 现在固定的公网IP基本上很难免费申请到了,但是一般来说运营商可以免费提供一个动态变化的公网IP:当路由设备重启时,运营 ...
- Protobuf动态解析
阅读目录 需求背景 技术介绍 实现 总结 参考文献 回到顶部 需求背景 在接收到 protobuf 数据之后,如何自动创建具体的 Protobuf Message 对象,再做反序列化."自动 ...
- 【网络安全】Metasploit 生成的 Shellcode 的导入函数解析以及执行流程分析(1)
2021 年 4 月,研究人员深入分析了 Cobalt Strike渗透测试技术,以及它的一些签名规避技术是如何在检测技术下失效的.在本文中,我们将深入讨论Metasploit,这是一个可以与Coba ...
- 路由器(结构、分组转发流程、路由选择协议(RIP、OSPF、BGP))
1. 路由器的结构 从功能上可以划分为:路由选择和分组转发. 分组转发结构由三个部分组成:交换结构.一组输入端口和一组输出端口. 2. 路由器分组转发流程 从数据报的首部提取目的主机的 IP 地址 D ...
- NGFW中数据包转发流程
状态检测防火墙报文处理流程 查询会话前的处理过程:基础处理 查询会话中的处理过程:转发处理,关键是会话建立 查询会话后的处理过程:安全业务处理及报文发送 了解转发流程之前,先给报文分个类 协议报文:使 ...
最新文章
- implementation ‘com.zxy.android:recovery:
- linux系统预定义变量有哪些,Shell预定义变量用法详解
- drf解决跨域问题 使用 django-corse-headers扩展
- 使用宝塔面板进行wordpress建站
- FSRNet:端到端深度可训练人脸超分辨网络
- Scikit-learn数据预处理分类变量编码之等级变量编码
- java中的model_Java程序员必看之springmvc中的Model对象在重定向中的数据
- 阿里巴巴旗下平台口碑推出无人收银技术,改造便利店市场;重庆法院运用 AI 探索“智能判案”...
- java get与post区别_HTTP请求(GET与POST区别)和响应
- C++ 11右值引用
- saas java框架_XMReport-提供web项目Java套打解决方案
- project不显示里程碑标志_在Project中设置里程碑
- php 重载进程,关于php-fpm与nginx进程重载
- TensorFlow——如何查看当前版本TF编译使用的CUDA和cuDNN的编译版本
- Java 线程——Timer TimerTask
- 惠普微型计算机怎么装机,台式小机惠普电脑怎么装系统
- 【经典策略系列】之 Dual Thrust 交易策略
- window10 tar解压
- swift ring
- java实现简单学生信息管理系统