博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
runtime(消息转发)
阅读量:6854 次
发布时间:2019-06-26

本文共 2136 字,大约阅读时间需要 7 分钟。

概况

当一个方法沿着类的继承链找不到实现时候,runtime会启动消息转发。消息转发一共有三步。

消息转发三步

  1. resolveInstanceMethod
#import "Cat.h"#import 
@implementation Cat+ (BOOL)resolveInstanceMethod:(SEL)sel{ if ([NSStringFromSelector(sel) isEqualToString:@"say"]) { class_addMethod(self, sel,(IMP)test , "v@:"); return YES; } return [super resolveInstanceMethod:sel];}void test(id self,SEL cmd){ NSLog(@"猫叫...");}@end复制代码
@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    Cat *aCat = [[Cat alloc] init];    [aCat say];}@end复制代码

在调用对象的所属类的实现文件新增resolveInstanceMethod方法。判断选择子是不是我们要进行转发的,如果不是返回super方法。如果是就新增方法的实现,并返回YES消息转发结束。

  1. forwardingTargetForSelector
#import "Dog.h"#import "Cat.h"#import 
@implementation Dog+ (BOOL)resolveInstanceMethod:(SEL)sel{ if ([NSStringFromSelector(sel) isEqualToString:@"say"]) { return NO; } return [super resolveInstanceMethod:sel];}- (id)forwardingTargetForSelector:(SEL)aSelector{ return [Cat new];}@end复制代码
@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    Dog *aDog = [[Dog alloc] init];    [aDog say];}@end复制代码

在调用所属类的实现文件里新增resolveInstanceMethod方法如果是当前选择子返回NO好进行消息转发第二步。接下来新增方法forwardingTargetForSelector返回cat对象。之后runtime系统会去cat类里去调用say的实现。

  1. forwardInvocation
#import "Dog.h"#import "Cat.h"#import 
@implementation Dog+ (BOOL)resolveInstanceMethod:(SEL)sel{ if ([NSStringFromSelector(sel) isEqualToString:@"say"]) { return NO; } return [super resolveInstanceMethod:sel];}- (id)forwardingTargetForSelector:(SEL)aSelector{ return nil;}- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{ return [NSMethodSignature signatureWithObjCTypes:"v@:"];}- (void)forwardInvocation:(NSInvocation *)anInvocation{ SEL aSel = anInvocation.selector; Cat *aCate = [Cat new]; if ([aCate respondsToSelector:aSel]) { [anInvocation invokeWithTarget:aCate]; }}@end复制代码

在调用类的实现文件里,新增resolveInstanceMethod方法返回NO,进入消息转发第二步。新增forwardingTargetForSelector方法返回nil,进入消息转发第三步。新增方法methodSignatureForSelector,forwardInvocation实现完整的消息转发。

转载于:https://juejin.im/post/5cf4b478f265da1bce3dbac0

你可能感兴趣的文章
pip更新
查看>>
python之enumerate()函数用法
查看>>
22、学PHP女生多吗,女生可学吗?
查看>>
DotNetTextBox V3.0 所见即所得编辑器控件 For Asp.Net2.0(ver 3.0.7Beta) 增加多语言!
查看>>
spring- 4.2.4
查看>>
基本数据结构学习总结: 二叉树的基本操作
查看>>
迟到的第四周
查看>>
09-数据库的备份和恢复
查看>>
JavaScript 实现深度拷贝
查看>>
【BZOJ1598】牛跑步 [A*搜索]
查看>>
直方图部分
查看>>
内存泄漏检测【转】
查看>>
快速排序,冒泡排序时间复杂度推导
查看>>
JavaScript 获取当前时间戳
查看>>
基础汇编指令
查看>>
C语言钙片
查看>>
《AjaxPro 教程系列》 一、环境配置和经典用例AutoComplete功能的实现
查看>>
spring+quartz的任务调度
查看>>
ActiveMq 总结(一)
查看>>
XJOI网上同步测试DAY14 T2
查看>>