iOS Objective -C Runtime 运行时之一: 类与对象

// ---------------------------------------------------

参考:南峰子的技术博客 http://southpeak.github.io

//----------------------------------------------------

OC语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理。这种动态语言的优势在于:我们编写代码时更具灵活性,如我们可以把消息转发给我们想要的对象,或者随意交换一个方法的实现等。

这种特性意味着OC不仅需要一个编译器,还需要一个运行时系统来执行编译的代码,对于OC来说,这个运行时系统就像一个操作系统一样,它让所有的工作可以正常的运行。这个运行时系统即Objc Runtime。 Objc Runtime其实是一个Runtime库,它基本上是用C喝汇编写的,这个库使得C语言有了面向对象的能力

Runtime库主要做下面几件事:

1.封装:在这个库中,对象可以用C语言中的结构体表示,而方法可以用C函数来实现,另外再加上了一些额外的特性。这些结构体和函数被runtime函数封装后,我们就可以在程序运行时创建、检查、修改类、对象和它们的方法了。

2.找出方法的最终执行代码:当程序执行[object doSomething]时,会向消息接收者(object)发送一条消息(doSomething),runtime会根据消息接收者是否能响应该消息而做出不同的反应。这将在后面详细介绍。

OC runtime目前有两个版本:Modern runtime和Legacy runtime。Modern Runtime覆盖了64位的Mac OS X Apps,还有iOS Apps,Legacy Runtime 是早起用来给32位Mac OS X Apps用的。

runtime的基本工作原理,以及如何利用它让程序编的更加灵活。

类与对象基础数据结构

Class

OC中,类是由Class 类型来表示的,它实际上是一个指向objc_class结构体的指针。定义如下:

typedef struct objc_claa *Class ;

查看objc/runtime.h中objc_class结构体的定义如下:

struct objc_class {
    Class isa OBJC_ISA_AVAILABILITY;

#if !__OBJC2__

Class super_class                           OBJC2_UNAVAILABLE; // 父类

const char *name                          OBJC2_UNAVAILABLE; // 类名

long version                OBJC2_UNAVAILABLE; // 类的版本信息,默认为0

long info                 OBJC2_UNAVAILABLE; // 类信息,供运行期使用的一些位标识

long instance_size             OBJC2_UNAVAILABLE; // 该类的实例变量大小

struct objc_ivar_list *ivars        OBJC2_UNAVAILABLE; // 该类的成员变量链表

struct objc_method_list  **methodLists   OBJC2_UNAVAILABLE; // 方法定义链表

struct objc_cache *cache        OBJC2_UNAVAILABLE;  // 方法缓存

struct objc_protocol_list *protocols   OBJC2_UNAVAILABLE;  // 协议链表

#endif

}OBJC2_UNAVAILABLE;

在这个定义中,下面几个字段是我们感兴趣的

1.isa: 需要注意的是,在OC中,所有的类自身也是一个对象,这个对象的Class里面也有一个isa指针,它指向metaClass(元类),后面详解

2.super class: 指向该类的父类,如果该类已经是最顶层的根类(如NSObject或NSProxy),则super_class为NULL.

3.cache: 用于缓存最近使用的方法. 一个接收者对象收到一个消息时,它会根据isa指针去查找能够响应这个消息的对象,在实际使用中,这个对象只有一部分方法是常用的,很多方法其实很少用或者根本用不上,这种情况下,如果每次消息来,我们都到methodLists中遍历一遍,性能势必很差,这时,cache就派上用场了,在我们每次调用过一个方法后,这个方法就会被缓存到cache列表中,下次调用的时候,runtime会优先去cache中查找,如果cache没有,采取methodLists中查找方法.这样,对于那些经常用到的方法的调用,便提高了调用的效率

4.version: 我们可以使用这个字段来提供类的版本信息,这对于类的序列化非常有用,它可以让我们识别出不同类定义版本中实例变量布局的改变,针对cache,下面例子来说明执行过程"

NSArray *array = [[NSArray alloc] init];

流程 :

  1.[NSArray alloc]执行, 因为NSArray 没有+alloc方法,于是去父类NSObject查找

    2.检测NSObject是否响应 + alloc方法,发现响应, 于是检测NSArray类,并根据其所需的内存空间开始分配内存,然后把isa指针指向NSArray类.同时,+alloc也被加进cache列表里

    3.接着,执行-init方法,如果NSArray响应方法,则直接将其加入cache;如果不响应,则取父类查找.

    4.在后期的操作中,如果再以[[NSArray alloc] init] 方式创建数组,则会直接从cache中取出相应的方法,直接调用

objc_object与id

objc_object是表示一个类的实例结构体,它的定义如下(objc/objc.h)

struct objc_object {

 Class isa OBJC_ISA_AVAILABILITY;

};

typedef struct objc_objct *id;

可以看到,这个结构体只有一个字,即指向其类的isa指针,这样,当我们向一个OC对象发送消息时,运行时库会根据实例对象的isa指针找到这个实例对象所属的类.Runtime库会在类的方法列表及父类的方法列表中寻找与消息对应的selector指向的方法.找到后即运行这个方法.

当创建一个特定类的实例对象时,分配的内存包含一个objc_object数据结构,然后是累的额实例变量的数据.NSObject类的alloc和allocWithZone:方法使用函数class_createInstance来创建objc_object数据结构.

另外还有我们常见的id,它是一个objc_object结构类型的指针.它的存在可以让我们实现类似于C++众泛型的一些操作,该类型的对象可以转换为任何一种对象,有点类似于C语言中void*指针类型的作用.

时间: 2024-10-27 10:20:59

iOS Objective -C Runtime 运行时之一: 类与对象的相关文章

iOS开发之runtime运行时机制

最近参加三次面试都有被问到runtime,也不知道面试官们自己懂不懂,反正就喜欢问,似乎就想把我唬住,来显示自己的对OC底层知识的理解很牛逼似的.(我现在开始看面试题,发现他们都喜欢问面试题的问题,我算明白了,都是应试教育惹的祸,大概他们以前没什么实际的app经验,所以准备了很多面试题,而我真的是能写app,先干活再找方法的人,面试不多,没什么面试经验,看来要开始碰壁多次才能掌握中国式面试).因为不太懂runtime我就只能支支吾吾的说点零碎.我真的好几次努力想看一看runtime的知识,因为知

Objective-C Runtime 运行时之一:类与对象

Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理.这种动态语言的优势在于:我们写代码时能够更具灵活性,如我们可以把消息转发给我们想要的对象,或者随意交换一个方法的实现等. 这种特性意味着Objective-C不仅需要一个编译器,还需要一个运行时系统来执行编译的代码.对于Objective-C来说,这个运行时系统就像一个操作系统一样:它让所有的工作可以正常的运行.这个运行时系统即Objc Runtime.Objc Runtime其实是一个Runti

[ObjectC]Runtime 运行时之一:类与对象

Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理.这种动态语言的优势在于:我们写代码时更具灵活性,如我们可以把消息转发给我们想要的对象,或者随意交换一个方法的实现等. 这种特性意味着Objective-C不仅需要一个编译器,还需要一个运行时系统来执行编译的代码.对于Objective-C来说,这个运行时系统就像一个操作系统一样:它让所有的工作可以正常的运行.这个运行时系统即Objc Runtime.Objc Runtime其实是一个Runtime

Runtime 运行时之一:类与对象

Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理.这种动态语言的优势在于:我们写代码时能够更具灵活性,如我们可以把消息转发给我们想要的对象,或者随意交换一个方法的实现等. 这种特性意味着Objective-C不仅需要一个编译器,还需要一个运行时系统来执行编译的代码.对于Objective-C来说,这个运行时系统就像一个操作系统一样:它让所有的工作可以正常的运行.这个运行时系统即Objc Runtime.Objc Runtime其实是一个Runti

Objective-O Runtime 运行时初体验

Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理.这种动态语言的优势在于:我们写代码时更具灵活性,如我们可以把消息转发给我们想要的对象,或者随意交换一个方法的实现等. 这种特性意味着Objective-C不仅需要一个编译器,还需要一个运行时系统来执行编译的代码.对于Objective-C来说,这个运行时系统就像一个操作系统一样:它让所有的工作可以正常的运行.这个运行时系统即Objc Runtime.Objc Runtime其实是一个Runtime

Runtime 运行时:类与对象

Runtime 运行时:类与对象 Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理.这种动态语言的优势在于:我们写代码时更具灵活性,如我们可以把消息转发给我们想要的对象,或者随意交换一个方法的实现等. 这种特性意味着Objective-C不仅需要一个编译器,还需要一个运行时系统来执行编译的代码.对于Objective-C来说,这个运行时系统就像一个操作系统一样:它让所有的工作可以正常的运行.这个运行时系统即Objc Runtime.Objc Ru

iOS开发——高级特性&Runtime运行时特性详解

Runtime运行时特性详解 本文详细整理了 Cocoa 的 Runtime 系统的知识,它使得 Objective-C 如虎添翼,具备了灵活的动态特性,使这门古老的语言焕发生机.主要内容如下: 引言 简介 与Runtime交互 Runtime术语 消息 动态方法解析 消息转发 健壮的实例变量(Non Fragile ivars) Objective-C Associated Objects Method Swizzling 总结 引言 曾经觉得Objc特别方便上手,面对着 Cocoa 中大量

iOS的runtime运行时机制

本文转自http://www.cnblogs.com/guoxiao/p/3583432.html 最近一直在研究runtime运行时机制的问题,我想可能也有很多人不太清楚这个问题吧?在这里跟大家沟通分享下我对与runtime机制的理解. 要理解runtime,首先我们要了解类和对象的内部结构,下面将首先介绍下OC中类与对象的结构层次. 一.首先,从 runtime.h头文件中找到对 class 与 object 的定义 /// An opaque type that represents an

runtime 运行时机制 完全解读

runtime 运行时机制 完全解读 目录[-] import import 我们前面已经讲过一篇runtime 原理,现在这篇文章主要介绍的是runtime是什么以及怎么用!希望对读者有所帮助! 首先,第一个问题, 1>runtime实现的机制是什么,怎么用,一般用于干嘛? 这个问题我就不跟大家绕弯子了,直接告诉大家, runtime是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API. 在我们平时编写的OC代码中, 程序运行过程时, 其实最终都是转成了runti