快速上手Runtime(一)之消息机制
Runtime简介
Runtime简称运行时。OC就是运行时机制,也就是在运行时候的一些机制,其中最主要的是消息机制。
对于C语言,函数的调用在编译的时候会决定调用哪个函数。
对于OC的函数,属于动态调用过程,在编译的时候并不能决定真正调用哪个函数,只有在真正运行的时候才会根据函数的名称找到对应的函数来调用。
事实证明:
在编译阶段,OC可以调用任何函数,即使这个函数并未实现,只要声明过就不会报错。
在编译阶段,C语言调用未实现的函数就会报错。
举个简单栗子:
NSString* testObject = [[NSData alloc] init]; testObject 在编译时和运行时分别是什么类型?
首先,声明 NSString *testObject
是告诉编译器,testObject
是一个指向某个Objective-C对象的指针。因为不管指向的是什么类型的对象,一个指针所占的内存空间都是固定的,所以这里声明成任何类型的对象,最终生成的可执行代码都是没有区别的。这里限定了NSString
只不过是告诉编译器,请把testObject
当做一个NSString
来检查,如果后面调用了非NSString
的方法,会产生警告。
接着,你创建了一个NSData
对象,然后把这个对象所在的内存地址保存在testObject
里。那么运行时,testObject
指向的内存空间就是一个NSData
对象。你可以把testObject
当做一个NSData
对象来用。
回归正题:
我们都知道一个对象的初始化可分为两步:
1.一个对象的初始化方法分解为两步: alloc 来开辟空间,init 来初始化 :id objc = [NSObject alloc];开辟内存空间,objc = [objc init];来初始化
2.第一步初始化过程用runtime来实现:
id objc = [NSObject alloc]; ---> id objc = objc_msgSend([NSObject class],@selector(alloc)));
objc = [objc init]; -------> objc = objc_msgSend(objc,@selector(init));
下面看栗子:
首先定义一个Person类
#import <Foundation/Foundation.h> @interface Person : NSObject - (void)name; + (void)name; @end #import "Person.h" @implementation Person - (void)name{ NSLog(@"对象方法---I'm doman"); } + (void)name{ NSLog(@"类方法---I'm doman"); } @end
通常情况下 我们都调用对象方法和类方法都是这样调的:
#pragma mark 如果是自己测试,请先移步Build Setting -> 搜索msg -> 设置属性为No //对象方法做法1 Person *p1 = [[Person alloc] init]; [p1 name]; //对象方法做法2 Person *p2 = [[Person alloc] init]; [p2 performSelector:@selector(name)]; // SEL:方法编号,根据方法编号就可以找到对应方法实现,此方法其实就是运用了运行时。 //类方法做法1 [Person name]; //类方法做法2--通过类对象调用 [[Person class] name];
其实上述方法的本质都是消息发送,那么接下来我们看用Runtime如何实现调用name方法:
1.第一步:引入Runtime框架import <objc/message.h>,注意,使用message,不使用<objc/runtime.h>的原因是message.h涵盖runtime,方法更全。
2.第二步:Build Setting -> 搜索msg -> 设置属性为No
3.使用objc_msgSend,方法;注意:只有对象才能发送消息,因此以objc开头.
// 让person发送消息-对象方法 Person *p3 = [[Person alloc]init]; objc_msgSend(p3,@selector(name)); //类方法使用runtime // 获取类对象 Class personClass = [Person class]; objc_msgSend(personClass, @selector(name));
调用结果:
Demo 地址:https://github.com/domanc/Runtime_Person.git