runtime详解

本文深入探讨Objective-C的runtime系统,包括其版本、平台、与runtime交互的方式、关键术语(如isa指针、SEL、Class、Method、Ivar、IMP、Cache、Property)、消息发送过程、动态方法解析和消息转发机制,以及健壮的实例变量Non Fragile ivars的概念。通过理解runtime,开发者可以更好地理解和利用Objective-C的动态特性。
摘要由CSDN通过智能技术生成

runtime 详解

本文结构:

  • 简介
  • runtime版本和平台
  • 与runtime交互
  • runtime术语
  • 消息
  • 动态方法解析
  • 消息转发
  • 健壮的实例变量
  • 总结

1、简介

Cocoa的Objective-C语言可以在编译和链接的时候不知道类或者成员变量,只有在runtime(运行时)的时候才知道它们。runtime是iOS的一套底层API。它就像是Objective-C的操作系统,处理并执行Objective-C语言。比如:

//一个OC的方法调用
[receiver message];
//编译器会把它编译为:
objc_msgSend(receiver,message);

//假如消息中含有参数,会转化为如下形式:
[receiver message:arg...];
objc_msgSend(receiver,message,arg1,arg2,...);

runtime会在运行的时候知道这些经过编译之后的代码,然后去执行它。

2、runtime版本和平台

  • logacy version: 运行在之前Objective-C 1.0的早期32位版本中。
  • modern version:现在我们用的就是modern version,运行在iOS 和OSX 10.5之后的64位程序中。

3、与runtime交互

Objective-C 源代码
runtime会在后台自动的给你执行这些编译过的代码,我们只需写Objective-C代码即可。当然了我们也可以直接写runtime相关的代码,类似上面的例子中objc_msgSend()函数等。消息的执行会使用到编译器为实现动态语言创建的数据结构和函数,Objective-C中的类、方法和协议等在runtime中都是有一些结构体来定义。如objc_msgSend()函数已经参数 id 和 SEL。
NSObject 方法
Cocoa 中的大部分方法都是继承与NSObject,也继承了它的方法。唯一特殊的是NSProxy,它是个抽象的超类,它实现了一些消息转发的方法,可以继承它实现一些类的替身类或者是虚拟出一个不存在的类。
有的方法起到了抽象接口的左右,比如description方法需要你在重载它并为你提供的类添加描述信息。NSObject还有一些方法能获取到运行时类的信息,比如class:返回对象的类;isKindOfClass:isMemberOfClassL:则检查对象是否存在某个类继承体系中;respondsToSelector则检查对象能否响应某方法;conformToProtocol则检查是否实现了指定的协议;mothodForSelector则返回方法实现的地址。
runtime的函数
runtime系统是一个有一些了函数和结构体组成,具有公共接口的动态库,头文件放在/usr/include/objc/文件里面,通过包含头文件#import <objc/runtime.h>就可以查看到这个头文件,里面的方法需要你通过编写C语言的方法来实现Objective-C的方法。在 Objective-C Runtime Reference中有对runtime函数的详细文档。

4、runtime术语

还是使用上面的objc_msgSend()方法吧,它的真身是

id objc_msgSend(id self,SEL op...)

id
objc_msgSend函数的第一个参数就是id,它是一个指向对象的指针。在/usr/include/objc/objc.h

typedef struct objc_object *id;

objc_object 是什么呢?

struct objc_object {
    Class isa  OBJC_ISA_AVAILABILITY;
};

objc_object它是一个含有isa指针,通过它就可以找到对象所属的类。
注:isa指针在代码运行的时候并不总指向实例所属的类,所有不能考它来确定类型,可以通过-class来确定。KVO的实现机理就是通过isa指针指向一个中间类而不是真实类型来实现。详情可看KVO的实现
SEL
objc_msgSend的第二个参数是SEL,它是selector在Objective-C中的表示。selector是一个方法选择器,可以理解为确保方法的ID,这个ID的数据结构是SEL

typedef struct objc_selector *SEL;

你可以用 Objc 编译器命令@selector()或者 Runtime 系统的sel_registerName函数来获得一个SEL类型的方法选择器。
Class
isa 是指针是因为Class 是一个指向objc_class结构体的指针:

typedef struct objc_class *Class;

而objc_class结构体里面包含许多信息

struct objc_class {
    Class isa  OBJC_ISA_AVAILABILITY;
    Class super_class ;
    const char *name ;
    long version ;
    long info ;
    long instance_size ;
    struct objc_ivar_list *ivars ;
    struct objc_method_list **methodLists ;
    struct objc_cache *cache ;
    struct objc_protocol_list *protocols ;
#endif

}

它有指向超类的super_class指针。其中 objc_ivar_list 是成员变量objc_ivar 列表;objc_method_list是objc_method方法列表。

    // 成员变量列表
    struct objc_ivar_list {
        int ivar_count                                           OBJC2_UNAVAILABLE;
    #ifdef __LP64__
        int space                                                OBJC2_UNAVAILABLE;
    #endif
        /* v
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值