iOS_Runtime1_消息发送机制

  • Runtime是运行时机制,是一套纯C的代码库,是OC的幕后工作者,整个OC的底层,我们编写的OC代码,在程序运行的时候,都经过Runtime机制转译成了C语言代码。
  • Runtime是运行时机制,其中最主要的是消息机制。
  • 对于C语言而言,函数的调用在编译的时候决定调用哪个函数。
  • 而对于OC而言,并不会在编译的时候真正决定调用哪个函数,只有在真正调用的时候,才会根据函数的名称找到对应的函数来调用。
  • 在编译阶段,OC可以调用任何已声明的函数,至于函数是否实现,并不重要。
  • 在编译阶段,C调用未实现的函数,将会报错。

验证Runtime的消息发送机制

  • 修改Xcode配置,在如图所示位置,将原来的YES修改为NO
    这里写图片描述
  • 验证消息发送机制代码如下:
// 1、创建一个集成自NSObject的类,并声明一些方法,实现这些方法
// Person.h
@interface Person : NSObject
- (void)sayHello;
- (void)sayMessage:(NSString *)message;
- (void)sayMessage:(NSString *)message WithBool:(BOOL)isBool;
@end
// Person.m
@implementation Person
- (void)sayHello{
    NSLog(@"Hello");
}
- (void)sayMessage:(NSString *)message{
    NSLog(@"%@",message);
}
- (void)sayMessage:(NSString *)message WithBool:(BOOL)isBool{
    if (isBool) {
        NSLog(@"%@",message);
    }
}
@end
// 2、验证消息发送机制代码如下:
//  ViewController.m
#import <objc/message.h>  // 需要导入此框架,验证消息发送机制
#import "Person.h"
//  验证代码示例如下:
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"----验证消息发送机制-开始----");
    // OC调用示例:
    [self exampleTransferWithOC];
    // 该行代码经过runtime就编译成了objc_msgSend(self,@selector(exampleTransferWithOC)); 向self发送exampleTransferWithOC方法
    // 消息发送机制示例:
    objc_msgSend(self, @selector(exampleTransferWithOC));
    NSLog(@"------分隔线--------");
    [self exampleTransferWithmsgSend];
    objc_msgSend(self, @selector(exampleTransferWithmsgSend));
    NSLog(@"------分隔线--------");
    // 验证
    [self otherTest];
    NSLog(@"----验证消息发送机制-结束----");
}

- (void)exampleTransferWithOC{
    Person *per = [[Person alloc]init];
    [per sayHello];
    [per sayMessage:@"说句话听听"];
}
- (void)exampleTransferWithmsgSend{
    id object = objc_msgSend([Person class], @selector(alloc));
    Person *per = objc_msgSend(object, @selector(init));
    objc_msgSend(per,@selector(sayHello));
    objc_msgSend(per, @selector(sayMessage:),@"我也会说hello");
    // 多个参数方法的消息发送
    objc_msgSend(per, @selector(sayMessage:WithBool:),@"我要说话",NO);

}
- (void)otherTest{
    Person *per = objc_msgSend(objc_msgSend(objc_getClass("Person"), sel_registerName("alloc")), sel_registerName("init"));
    objc_msgSend(per,sel_registerName("sayHello"));
    /*
     objc_getClass("Person")表示获得类对象,等同于[Person class]
     sel_registerName("alloc")表示注册一个方法,等同于@selector(alloc)
     */
}

@end

Runtime的作用

Runtime的作用:
1. 动态添加方法(KVO中,监听数组)
2. 动态生成类(KVO机制中,系统动态为我们生成了一个中间类,帮助我们完成观察者对象和被观察对象数据的传递)
3. 动态获取每个类中的属性名和实例变量名


总结:

  1. runtime 验证必须导入头文件<objc/message.h>
  2. 任何方法的调用,其本质就是消息的发送;利用runtime进行消息的发送,Objective-C的底层实现就是利用runtime实现的。
  3. 验证消息发送机制时,需要更改Xcode配置,查找build setting -> 搜索msg,设置为NO。
  4. 验证消息发送机制时,主要是利用方法id objc_msgSend(id self, SEL op, ...),参数id self是指消息的接受者,也是方法的执行者,例如上述的对象per;参数SEL op 是指发送的消息,也就是方法执行者将要执行的方法;后续的参数是发送消息的附带参数,也就是指方法的参数;返回值是一个泛指类型。
  5. 利用runtime消息发送机制,可以调用系统API中或是框架中的私有方法。
  6. 方法列表的位置:如果是对象方法,位于类对象的方法列表;如果是类方法,则位于元类中的方法列表。
  7. runtime消息发送机制,方法调用过程。
    • 例如如何去调用对象方法sayHello:通过isa指针去对应的类中查找 -> 注册方法编号 -> 根据方法编号去查找对应方法(找到只是最终函数实现地址,根据地址去方法区调用对应函数)
    • 总的来说:一个对象被初始化后,内部会有一个isa指针,指向类对象(类对象的方法列表),类对象中会有一个方法列表,此时会根据方法列表注册方法编号,方法编号对应方法列表,根据方法编号查找对应的方法,找到的只是最终函数的实现地址,根据地址去内存中的方法区调用对应函数

iOS_Runtime2_方法交换

iOS_Runtime3_动态添加方法

iOS_Runtime4_动态添加属性

iOS_Runtime5_消息转发

iOS_Runtime6_字典转化为模型应用


代码地址:
https://github.com/FlyingKuiKui/RunTime.git

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值