简而言之,Objective-C Runtime是一个将C语言转化为面向对象语言的扩展。 我们将C++和Objective进行对比,虽然C++和Objective-C都是在C的基础上加入面向对象的特性扩充而成的程序设计语言,但二者实现的机制差异很大。C++是基于静态类型,而Objective-C是基于动态运行时类型。也就是说用C++编写的程序编译时就直接编译成了可令机器读懂的机器语言;用Objective-C编写的程序不能直接编译成可令机器读懂的机器语言,而是在程序运行的时候,通过Runtime把程序转为可令机器读懂的机器语言。Runtime是Objective不可缺少的重要一部分。
Runtime其实有两个版本: “modern” 和 “legacy”。我们现在用的 Objective-C 2.0 采用的是现行 (Modern) 版的 Runtime 系统,只能运行在 iOS 和 macOS 10.5 之后的 64 位程序中。而 macOS 较老的32位程序仍采用 Objective-C 1 中的(早期)Legacy 版本的 Runtime 系统。这两个版本最大的区别在于当你更改一个类的实例变量的布局时,在早期版本中你需要重新编译它的子类,而现行版就不需要。
runtime是一个c和汇编写的动态库,它就像一个小小的系统,将OC和C紧密关联,这个系统主要做两件事 :
1、封装C语言的结构体和函数,让开发者在运行时创建、检查或者修改类、对象和方法等等。2、传递消息,找出方法的最终执行代码。 1、无参数OC定义方法
[receiver message]runtime转化C语言的代码:
objc_msgSend(receiver, selector) 2、有参数OC定义方法
[receiver message:arg1 ...]runtime转化C语言的代码:
objc_msgSend(receiver, selector, arg1, arg2, ...) 3、多方法OC定义方法
NSObject *object = [[NSObject alloc] init];runtime转化C语言的代码:
objc_msgSend(objc_msgSend([NSObject class],@selector(alloc)),@selector(init));bjc 从三种不同的层级上与 Runtime 系统进行交互,分别是:
通过 Objective-C 源代码通过 Foundation 框架的NSObject类定义的方法通过对 runtime 函数的直接调用。编写OC代码,程序在运行时,runtime会自动将OC转化成C语言代码。
Cocoa 中大多数类都继承于NSObject类,也就自然继承了它的方法。最特殊的例外是NSProxy,它是个抽象超类,它实现了一些消息转发有关的方法,可以通过继承它来实现一个其他类的替身类或是虚拟出一个不存在的类。
有的NSObject中的方法起到了抽象接口的作用,比如description方法需要你重载它并为你定义的类提供描述内容。NSObject还有些方法能在运行时获得类的信息,并检查一些特性,比如class返回对象的类;isKindOfClass:和isMemberOfClass:则检查对象是否在指定的类继承体系中;respondsToSelector:检查对象能否响应指定的消息;conformsToProtocol:检查对象是否实现了指定协议类的方法;methodForSelector:则返回指定方法实现的地址。
Runtime 系统是一个由一系列函数和数据结构组成,具有公共接口的动态共享库。头文件存放于/usr/include/objc目录下。许多函数允许你用纯C代码来重复实现 Objc 中同样的功能。虽然有一些方法构成了NSObject类的基础,但是你在写 Objc 代码时一般不会直接用到这些函数的,除非是写一些 Objc 与其他语言的桥接或是底层的debug工作。
objc_msgSend:方法,它的真身是这样的:
id objc_msgSend ( id self, SEL op, ... );objc_msgSend第一个参数类型为id,它是一个指向类实例的指针:
// objc-private.h typedef struct objc_object *id;objc_object定义如下:
// objc-private.h struct objc_object { private: isa_t isa; }objc_class定义如下:
//objc-runtime-new.h struct objc_class : objc_object { // Class ISA; Class superclass; cache_t cache; // formerly cache pointer and vtable class_data_bits_t bits; // class_rw_t * plus custom rr/alloc flags }cache_t的定义如下:
//objc-runtime-new.h struct cache_t { static bucket_t *emptyBuckets(); struct bucket_t *buckets(); mask_t mask(); mask_t occupied(); void incrementOccupied(); void setBucketsAndMask(struct bucket_t *newBuckets, mask_t newMask); void initializeToEmpty(); unsigned capacity(); bool isConstantEmptyCache(); bool canBeFreed(); };class_data_bits_t定义如下:
//objc-runtime-new.h struct class_data_bits_t { // Values are the FAST_ flags above. uintptr_t bits; public: class_rw_t* data() const { return (class_rw_t *)(bits & FAST_DATA_MASK); } const class_ro_t *safe_ro() { class_rw_t *maybe_rw = data(); if (maybe_rw->flags & RW_REALIZED) { // maybe_rw is rw return maybe_rw->ro(); } else { // maybe_rw is actually ro return (class_ro_t *)maybe_rw; } } };method_t的定义如下:
struct method_t { SEL name; const char *types; MethodListIMP imp; struct SortBySELAddress : public std::binary_function<const method_t&, const method_t&, bool> { bool operator() (const method_t& lhs, const method_t& rhs) { return lhs.name < rhs.name; } }; };