知识总结Objective-C Runtime 运行时(1)

本文详细介绍了Objective-C的运行时机制,包括类结构、方法列表、缓存机制及协议等核心概念。通过具体实例展示了如何利用Runtime库动态获取类信息、方法及属性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

c语言不是动态语言,函数的调用在编译时候已经确定,编译完成后按照顺序执行即可。OC作为动态语言主要是因为Runtime库的支持,由于Runtime库的作用使得c语言具有了动态语言的特性,runtime保持在程序运行时创建,修改类,对象和方法,OC的函数调用通过runtime进行消息的转发。
Object-C类

typedef struct objc_class *Class;

struct objc_class {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
    Class _Nullable super_class                              OBJC2_UNAVAILABLE;//父类
    const char * _Nonnull name                               OBJC2_UNAVAILABLE;//类名
    long version                                             OBJC2_UNAVAILABLE;//类的版本信息
    long info                                                OBJC2_UNAVAILABLE;//类信息运行时的使用的标识位
    long instance_size                                       OBJC2_UNAVAILABLE;//实例变量大小
    struct objc_ivar_list * _Nullable ivars                  OBJC2_UNAVAILABLE;//成员变量列表
    struct objc_method_list * _Nullable * _Nullable methodLists                    OBJC2_UNAVAILABLE;//方法列表
    struct objc_cache * _Nonnull cache                       OBJC2_UNAVAILABLE;//方法缓存
    struct objc_protocol_list * _Nullable protocols          OBJC2_UNAVAILABLE;//协议列表
#endif

} OBJC2_UNAVAILABLE;

下面定义两个类,并以此举例说明runtime

@interface Father : NSObject
@property (nonatomic, strong) NSString *property_1_s;
@property (nonatomic, weak) NSArray *property_2_w;
@property (nonatomic, unsafe_unretained) id property_3_un;
@property (nonatomic, weak) id property_4_w;
@property (nonatomic, strong) id property_5_s;
@property (nonatomic, strong) id property_6_s;
@property (nonatomic, unsafe_unretained) id property_7_un;
@property (nonatomic, strong) id property_8_s;
@property (nonatomic, strong) id property_9_s;
@property (nonatomic, weak) id property_10_w;
@property (nonatomic, weak) id property_11_w;
@property (nonatomic, strong) id property_12_s;
@property (nonatomic, weak) id property_13_s;
@end

@interface Son : Father

@end
Father *father = [[Father alloc] init];
Son *son = [[Son alloc]init];

(1)isa:指向metaClass(元类),元类顾名思义也是一个类,存储对象的类方法。

    NSLog(@"This object is %p.", son);
    Class currentClass = [son class];
    for (int i = 1; i < 5; i++)
    {
        NSLog(@"Following the isa pointer %d  times gives %p", i, currentClass);
        currentClass = object_getClass(currentClass);
    }
    NSLog(@"NSObject's class is %p", [NSObject class]);
    NSLog(@"NSObject's meta class is %p", object_getClass([NSObject class]));

这里写图片描述
可以看出对象son的地址开辟在堆中,其类地址为0x109e80568,其isa指针指向的meta-class地址为0x109e80540,meta-class所属类的地址为0x10ae38e58,通过打印NSObject的地址可以看出meta-class继承了NSObject。
(2)super_class 指向父类,如果该类是最顶层根类如NSObject则其super_class为NULL。

(3)name 类名Father, Son
(4)version 该字段提供类的版本信息,可以识别出不同定义版本中的实例变量布局的改变
(5)instance_size 实例变量大小

NSInteger instance_size = class_getInstanceSize([father class]);
NSLog(@"instance_size = %d",instance_size);

这里写图片描述
father含有13个属性都是指针类型和1个isa指针,一共112字节。
(6)ivars 它指向objc_ivar_list结构体,objc_ivar_list其实就是一个链表,存储多个objc_ivar,而objc_ivar结构体存储类的单个成员变量信息。

struct objc_ivar_list {
    int ivar_count                                           OBJC2_UNAVAILABLE;
#ifdef __LP64__
    int space                                                OBJC2_UNAVAILABLE;
#endif
    /* variable length structure */
    struct objc_ivar ivar_list[1]                            OBJC2_UNAVAILABLE;
} 
    unsigned int outCount =0;
    Ivar*ivars =class_copyIvarList(father.class, &outCount);
    for(unsigned int i =0; i < outCount; ++i) {
        Ivar ivar = ivars[i];
        const char*ivarName =ivar_getName(ivar);
        const char*ivarEncoder =ivar_getTypeEncoding(ivar);
        NSLog(@"Ivar name:%s Ivar TypeEncoder:%s",ivarName,ivarEncoder);
    }
    free(ivars);

这里写图片描述

(7)methodLists表示方法列表,它指向objc_method_list结构体的二级指针,可以动态修改*methodLists的值来添加成员方法,也是category的实现原理。

struct objc_method_list {
    struct objc_method_list * _Nullable obsolete             OBJC2_UNAVAILABLE;

    int method_count                                         OBJC2_UNAVAILABLE;
#ifdef __LP64__
    int space                                                OBJC2_UNAVAILABLE;
#endif
    /* variable length structure */
    struct objc_method method_list[1]                        OBJC2_UNAVAILABLE;
}

objc_method_list也是一个链表,存储多个objc_method,而objc_method结构体存储类的某个方法的信息。

typedef struct objc_method *Method;  
struct objc_method {  
    SEL method_name                                          OBJC2_UNAVAILABLE;  
    char *method_types                                       OBJC2_UNAVAILABLE;  
    IMP method_imp                                           OBJC2_UNAVAILABLE;  
}

Method是一个指向objc_method结构体指针,它存储了方法名(method_name)、方法类型(method_types)和方法实现(method_imp)等信息。而method_imp的数据类型是IMP,它是一个函数指针

(8)cache用于缓存最近使用的方法。一个对象接收到一个消息时,对象会根据isa指针去查找能够响应这个消息的对象。每次调用过一个方法后,这个方法就会被缓存到cache列表中,下次调用的时候runtime就会优先去cache中查找,如果cache没有,才去methodLists中查找方法。这样,对于那些经常用到的方法的调用,但提高了调用的效率。objc_cache结构体的指针,其定义如下:

struct objc_cache {
    unsigned int mask /* total = mask + 1 */                 OBJC2_UNAVAILABLE;
    unsigned int occupied                                    OBJC2_UNAVAILABLE;
    Method _Nullable buckets[1]                              OBJC2_UNAVAILABLE;
};

(9)protocols类遵循的协议,协议列表objc_protocol_list定义如下:

typedef struct objc_object Protocol;//isa指针
struct objc_protocol_list {
    struct objc_protocol_list * _Nullable next;
    long count;
    __unsafe_unretained Protocol * _Nullable list[1];
};
资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在当今的软件开发领域,自动化构建与发布是提升开发效率项目质量的关键环节。Jenkins Pipeline作为一种强大的自动化工具,能够有效助力Java项目的快速构建、测试及部署。本文将详细介绍如何利用Jenkins Pipeline实现Java项目的自动化构建与发布。 Jenkins Pipeline简介 Jenkins Pipeline是运行在Jenkins上的一套工作流框架,它将原本分散在单个或多个节点上独立运行的任务串联起来,实现复杂流程的编排与可视化。它是Jenkins 2.X的核心特性之一,推动了Jenkins从持续集成(CI)向持续交付(CD)及DevOps的转变。 创建Pipeline项目 要使用Jenkins Pipeline自动化构建发布Java项目,首先需要创建Pipeline项目。具体步骤如下: 登录Jenkins,点击“新建项”,选择“Pipeline”。 输入项目名称描述,点击“确定”。 在Pipeline脚本中定义项目字典、发版脚本预发布脚本。 编写Pipeline脚本 Pipeline脚本是Jenkins Pipeline的核心,用于定义自动化构建发布的流程。以下是一个简单的Pipeline脚本示例: 在上述脚本中,定义了四个阶段:Checkout、Build、Push packageDeploy/Rollback。每个阶段都可以根据实际需求进行配置调整。 通过Jenkins Pipeline自动化构建发布Java项目,可以显著提升开发效率项目质量。借助Pipeline,我们能够轻松实现自动化构建、测试部署,从而提高项目的整体质量可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值