runtime(一):消息机制

会oc不会runtime就是不懂oc。近期项目需要做一些热更新,顺带着复习一下。

首先必须知道的是,oc的消息机制。废话不多说,直接上代码和注释。

//
//  main.m
//  rumtime
//
//  Created by 123 on 16/7/4.
//  Copyright © 2016年 yipinbaike. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <objc/message.h>

@interface Person : NSObject
- (void)run;
+ (void)run;
- (void)eatWith:(NSString*)food;
@end
@implementation Person
- (void)run
{
    NSLog(@"对象方法run");
}
+ (void)run{
    NSLog(@"类方法run");
}
- (void)eatWith:(NSString*)food{
    NSLog(@"吃了:%@",food);
}
@end

void text1();
void text2();
int main(int argc, const char * argv[]) {
    @autoreleasepool {
//        text1();
        text2();
    }
    return 0;
}

#pragma mark --消息机制
/*
    oc方法和c语言函数是不一样的,oc在编译的时候是不知道真正调用的是哪个函数,只有真正的在运行的时候才会通过函数名找到真正要调用的函数
    oc语言采用的是消息机制,例如在text1中,调用的循序一次是从上到下三个方法。
 */
//1.测试消息机制(不含参)
void text1(){
    //实例对象方法
    Person * person = [[Person alloc]init];
    [person run];
    [person performSelector:@selector(run)];
    objc_msgSend(person,@selector(run));
    //类对象方法
    //需要注意的是,直接使用 objc_msgSend(Person, @selector(run)) 是不被允许的。因为类方法的调用的实质是:将类名转化成类对象。而Person只是一个类名,不能直接调用消息函数 objc_msgSend()
    Class personClass = [Person class];
    [personClass run];
    [personClass performSelector:@selector(run)];
    objc_msgSend(personClass, @selector(run));
}
//2.测试消息机制(含参)
void text2(){
    //注意 performSelector 这个函数的传参的个数有限,一般是用字典或者数组来做这种处理
    Person * person = [[Person alloc]init];
    [person eatWith:@"包子"];
    [person performSelector:@selector(eatWith:) withObject:@"包子"];
    objc_msgSend(person, @selector(eatWith:),@"包子");
}

需要注意的是

1.运行以上代码需要导入#import <objc/message.h>

2.需要在Build Setting -> 搜索msg -> 设置属性为No(取消消息机制的检查)

时间: 2024-08-10 18:27:01

runtime(一):消息机制的相关文章

iOS开发runtime学习:一:runtime简介与runtime的消息机制

一:runtime简介:也是面试必须会回答的部分 二:runtime的消息机制 #import "ViewController.h" #import <objc/message.h> #import "Person.h" /* 总结: 1: runtime:必须要导入头文件 <objc/message.h>,此头文件中已经引入了<objc/runtime.h> 任何方法调用本质:发送一个消息,用runtime发送消息.OC底层实现

RunTime 动态消息机制

##什么是RunTime机制 oc在编译的时是不知道调用哪个函数,运行时找不到就报错 C语言在编译的时候就知道调用哪个方法 [p eat] 消息机制 任何方法调用 本质都是发送消息 [p performSelector:@selector(<#selector#>)] #import <objc/message.h> 倒入运行时框架 运行时发送消息 谁做事情就去调用谁 xcode5以后 不给底层的方法让开发者调用 调用类方法 其实 就是变成一个类对象 本质 类名转换成类对象 分类没

runtime总结二之消息机制(包括消息转发,消息交换的黑魔法)

runtime的消息机制 前面提到过编译器最终会把我们的消息发送转化为函数调用 消息发送 [object sendMassage] 首先编译器会在运行时将上面的例子转化为objc_msgSend(obj,@selector(sendMassage))这个函数,转换的时候除了方法本身的参数之外,还有两个隐藏的参数一个是id类型的,代表对象的类型,还是一个是SEL类型的,是函数对应的方法的编号,接下来就会按照下面的流程来调用这个方法 通过obj的isa指针找到其所对应的类. 通过SEL先去类的cac

Objective-C总Runtime的那点事儿(一)消息机制

Objective-C总Runtime的那点事儿(一)消息机制 RunTime简称运行时.就是系统在运行的时候的一些机制,其中最主要的是消息机制.对于C语言,函数的调用在编译的时候会决定调用哪个函数( C语言的函数调用请看这里 ).编译完成之后直接顺序执行,无任何二义性.OC的函数调用成为消息发送.属于动态调用过程.在编译的时候并不能决定真正调用哪个函数(事实证明,在编 译阶段,OC可以调用任何函数,即使这个函数并未实现,只要申明过就不会报错.而C语言在编译阶段就会报错).只有在真正运行的时候才

NSObject头文件解析 / 消息机制 / Runtime解读 (二)

本章接着NSObject头文件解析 / 消息机制 / Runtime解读(一)写 给类添加属性: BOOL class_addProperty(Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount) 其中有一个参数我们再在上一篇中提到过 typedef struct { const char *name;           /**< The na

Runtime那些事儿(消息机制)

一.关于runtime 之前在项目中有遇到过用runtime解决改变全局字体的问题,所以再一次感受到了runtime黑魔法的强大,趁现在有机会分享一下对runtime的一些理解.在对象调用方法是Objective-C中经常使用的功能,也就是消息的传递,而Objective-C是C的超集,所以和C不同的是,Objective-C使用的是动态绑定,也就是runtime.Objective-C的消息传递和消息机制也就不多说了,今天主要说的是动态方法,也就是函数的调用. 二.相关的几个函数 下面一张图详

NSObject头文件解析 / 消息机制 / Runtime解读 (一)

NSObject头文件解析 当我们需要自定义类都会创建一个NSObject子类, 比如: #import <Foundation/Foundation.h> @interface ClassA : NSObject @end 那么NSObject里面具体有什么呢? 我们点到它的头文件里面去看看 @interface NSObject <NSObject> { Class isa OBJC_ISA_AVAILABILITY; //每个NSObject对象都拥有一个Class类作为成员

Objective-C总Runtime的那点事儿(一)消息机制【转】

RunTime简称运行时.就是系统在运行的时候的一些机制,其中最主要的是消息机制.对于C语言,函数的调用在编译的时候会决定调用哪个函数( C语言的函数调用请看这里 ).编译完成之后直接顺序执行,无任何二义性.OC的函数调用成为消息发送.属于动态调用过程.在编译的时候并不能决定真正调用哪个函数(事实证明,在编 译阶段,OC可以调用任何函数,即使这个函数并未实现,只要申明过就不会报错.而C语言在编译阶段就会报错).只有在真正运行的时候才会根据函数的名称找 到对应的函数来调用. 那OC是怎么实现动态调

RunTime(消息机制) + RunTime(消息转发)

一.消息机制 1.在viewDidLoad中直接用 performSelector:@selector(doSomething) 来调用doSomething方法时,会发现找不到这个方法而奔溃.此时,我们可以在resolveInsantanceMethod:(SEL)see 方法中获取这个所有在运行时阶段的方法,在这个方法中只需要判断一下,将这个方法获取,并且运用Runtime 的 class_addMethod 的方法来将方法和响应函数绑定,进而达到为某一个类添加方法的目的. - (void)