Objective-C的对象模型和runtime机制「建议收藏」

Objective-C的对象模型和runtime机制

大家好,又见面了,我是全栈君。

内容列表

  • 对象模型(结构定义,类对象、元类和实例对象的关系)
  • 消息传递和转发机制
  • runtime系统功能理解

对象模型

结构定义

对象(Object): OC中基本构造单元 (building block),用于存储和传递数据。

能够在objc.h的文件里查找到对象结构的定义,例如以下所看到的即对象结构为Class类型的isa,而Class是 objc_class结构类型指针。

objc_class即我们理解的类对象结构。其也包含一个isa类对象结构指针。

类和对象的终于实现都是一种数据结构,(subclass is an instance of superclass)

  • 对象结构
/// Represents an instance of a class.
struct objc_object {
    Class isa  OBJC_ISA_AVAILABILITY;
};
  • id类型定义
/// A pointer to an instance of a class.
typedef struct objc_object *id;
  • Class类型定义
/// An opaque type that represents an Objective-C class.
typedef struct objc_class *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;
    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;

类(类对象)、元类(元类对象)和实例对象的关系

一个完整的类应该包含类方法、实例方法和成员变量(实例变量), 每一个对象都包含一个isa(is a class)指针指向类对象(执行时方法发送给对象消息,才确定类别并调用相应的方法实现)。类对象结构中记载了类的全部信息。

类对象的isa指向元类对象(meta class),类对象中的方法列表是实例方法(-, instance methods)。 元类对象中的方法列表是类方法(+, class methods)

  • 能够这么理解:

    类包含类对象和元类对象,它们通过类对象结构定义,构成类的全部信息。在定义实例对象的时候,并不会进行不论什么存储空间(堆)分配,直到调用类方法alloc函数和实例方法init函数实现实例对象在堆中的结构存储分配。并将isa指向其类对象。父类成员变量和相应类对象成员变量初始化为0或nil

上述理解能够通过以下代码和对象变量结构分析来进行确认。

  • 測试代码
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@interface AClass : NSObject
{
    int a;
    char cA;
}

- (void)printA;

@end

@implementation AClass

- (void)printA
{
    NSLog(@"I am class A~");
}

@end

@interface BClass : AClass
{
    int b;
    char cB;
}

- (void)printB;

@end

@implementation BClass

- (void)printB
{
    NSLog(@"I am class B~");
}

@end


// ---------- main ----------
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // ******对象模型初探******
        AClass *a = [[AClass alloc] init];
        BClass *b = [[BClass alloc] init];
        BClass *b1;
        [a printA];
        [b printB];
        }
        return 0;
 }
  • 查看对象变量结构(通过设置断点进入Debug模式查看)

Instance Structure

  • 类对象、元类和实例对象的isa指针调用图示(subclass is a instance of superclass)

(1) Root class 是NSObject, NSObject没有超类。superclass -> nil

(2) 每一个类对象都有一个isa指向唯一的Meta class

(3) 每一个元类对象的 isa指针都指向 NSObject的元类对象
这里写图片描写叙述

消息传递和转发机制

消息传递(Messaging): 在对象之间传递数据并执行任务的过程

Objective-C基于C语言加入了面向对象特性和消息转发机制的动态语言。除编译器外还须要用Runtime系统来动态创建类和对象进行消息发送和转发。

不同语言有不同函数传递方法,C语言 - 函数指针,C++ - 函数调用(引用)类成员函数在编译时候就确定了其所属类别, Objective-C 通过选择器和block。

Objective-C强调消息传递而非方法调用。

能够向一个对象传递消息,且不须要再编译期声明这些消息的处理方法。

这些方法在执行时才确定。执行时(runtime)详细功能将在以下介绍。

[receiver message];
并不会立即执行 receiver 对象的 message方法的代码。而是向receiver发送一条message消息,该句话被编译器转化为:

id obj_msgSend(id self, SEL op, …);

PS: 消息调用函数还存在特殊情况,如其它函数
objc_msgSend_stret //待发送消息返回结构体
objc_msgSend_fpret //返回浮点数
objc_msgSendSuper //给超类发消息

SEL 表示方法选择器,结构例如以下: typedef struct objc_selector*SEL。, 可通过关键字@selector()获得

id 数据结构在第一部分:对象模型中已经有定义。

obj_msgSend 发消息流程:

  • 依据receiver 对象的isa类对象指针获取相应的class(类对象);
  • 优先在类对象的cache(fast map)查找message方法,Not find ->再到methodLists(类中的调度表,用于映射方法和实际内存地址。同一时候类中还包含指向父类的指针)查找;
  • 假设没有在class象里找到。再到super_class查找。
  • 假设找到message这种方法,执行它的实现IMP
  • 假设找不到消息。则执行消息转发(message forwarding)

Method数据结构 runtime.h头文件里定义:

typedef struct objc_method *Method;
struct objc_method { SEL method_name; // 特殊的字符串。描写叙述方法名, 能够通过关键字 @selector( ) 获取 char *method_types; IMP method_imp; }

PS:消息转发分为两大阶段即动态加入方法解析(dynamic method resolution)和完整的消息转发机制(full forward mechanism)

runtime系统功能理解

runtime : 程序执行后。提供相关支持的代码叫做OC执行期环境(OC runtime),它提供了对象间传递消息的重要函数(比方objc_msgSend),而且包含创建类实例所用的全部逻辑(即创建实例对象的存储结构和空间,包含isa指向“类对象”的指针)

runtime系统是一个用C语言编写动态链接库,核心是消息分发。Runtime机制包含对象模型。消息传递和转发。方法实现机制和其它执行时方法。能够实现动态创建改动类对象和对象等功能,消息传递和转发,方法动态实现,Method Swizzling等功能。

##Objective-C程序生成目标文件里的执行时信息怎样获取?
对于一个OC的.m程序文件,在Terminal输入命令:
gcc -framework Foundation main.m -o p1
当然。执行命令即: ./p1
然后,通过 otool 工具获取目标文件(包含头部、载入指令、各个segment)中执行时信息(有专门的segment保存)
otool -o p1

PS 我们能够通过获取执行时信息了解对象模型中元类对象和类对象结构等信息,例如以下所看到的。能够清晰看到类对象列表和元类映射关系,结构信息

p1:
Contents of (__DATA,__objc_classlist) section
0000000100001098 0x100001310
           isa 0x1000012e8
    superclass 0x0
         cache 0x0
        vtable 0x0
          data 0x100001160 (struct class_ro_t *)
                    flags 0x0
            instanceStart 8
             instanceSize 13
                 reserved 0x0
               ivarLayout 0x0
                     name 0x100000f60 AClass
              baseMethods 0x1000010f8 (struct method_list_t *)
          entsize 24
            count 1
              name 0x100000f6e printA
            types 0x100000f91 v16@0:8
              imp 0x100000d90
            baseProtocols 0x0
                    ivars 0x100001118
                    entsize 32
                      count 2
              offset 0x1000012c8 8
                name 0x100000f75 a
                type 0x100000f99 i
            alignment 2
                size 4
              offset 0x1000012d0 12
                name 0x100000f77 cA
                type 0x100000f9b c
            alignment 0
                size 1
           weakIvarLayout 0x0
           baseProperties 0x0
Meta Class
           isa 0x0
    superclass 0x0
         cache 0x0
        vtable 0x0
          data 0x1000010b0 (struct class_ro_t *)
                    flags 0x1 RO_META
            instanceStart 40
             instanceSize 40
                 reserved 0x0
               ivarLayout 0x0
                     name 0x100000f60 AClass
              baseMethods 0x0 (struct method_list_t *)
            baseProtocols 0x0
                    ivars 0x0
           weakIvarLayout 0x0
           baseProperties 0x0
00000001000010a0 0x100001360
           isa 0x100001338
    superclass 0x100001310
         cache 0x0
        vtable 0x0
          data 0x100001258 (struct class_ro_t *)
                    flags 0x0
            instanceStart 16
             instanceSize 21
                 reserved 0x0
               ivarLayout 0x0
                     name 0x100000f67 BClass
              baseMethods 0x1000011f0 (struct method_list_t *)
          entsize 24
            count 1
              name 0x100000f7a printB
            types 0x100000f91 v16@0:8
              imp 0x100000dc0
            baseProtocols 0x0
                    ivars 0x100001210
                    entsize 32
                      count 2
              offset 0x1000012d8 16
                name 0x100000f81 b
                type 0x100000f99 i
            alignment 2
                size 4
              offset 0x1000012e0 20
                name 0x100000f83 cB
                type 0x100000f9b c
            alignment 0
                size 1
           weakIvarLayout 0x0
           baseProperties 0x0
Meta Class
           isa 0x0
    superclass 0x1000012e8
         cache 0x0
        vtable 0x0
          data 0x1000011a8 (struct class_ro_t *)
                    flags 0x1 RO_META
            instanceStart 40
             instanceSize 40
                 reserved 0x0
               ivarLayout 0x0
                     name 0x100000f67 BClass
              baseMethods 0x0 (struct method_list_t *)
            baseProtocols 0x0
                    ivars 0x0
           weakIvarLayout 0x0
           baseProperties 0x0
Contents of (__DATA,__objc_classrefs) section
00000001000012b8 0x100001310
00000001000012c0 0x100001360
Contents of (__DATA,__objc_imageinfo) section
  version 0
    flags 0x0

參考资源

Effective Objective-C 2.0
Objective-C的对象模型与执行时
深入理解Objective-C的Runtime机制
Objective-C的动态特性

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/115382.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 晨跑感悟:三快三爽三熬

    晨跑感悟:三快三爽三熬

    2021年11月15日
  • 前端VsCode使用插件

    前端VsCode使用插件vscode前端插件

  • 虚拟存储

    虚拟存储为解决日益增长的内存需要,有以下几种解决办法:1.覆盖:将程序划分成几个模块,将没有调用关系的模块(即不会同时运行的模块)分成一组,其中每组所占的内存大小为组内所需内存最大的模块的内存,然后一组内

  • 如何实现微信上制作活动链接「建议收藏」

    如何实现微信上制作活动链接「建议收藏」随着互联网的快速发展,无论是房产、装修检查、家居、家店还是商城、餐饮等行业,商家们都会用到活动预约报名,线上活动链接的制作不仅成本低,而且受众也广,可以达到快速宣传的效果。相信很多小伙伴们在微信朋友圈看到的微信活动报名链接很好奇,这种活动链接是如何实现的,希望自己也可以在微信上制作这种活动链接。    工预善其事必先利其器,在这里,咱不能不提到一个非常好用的微信活动制作神器—获客宝。这款软件的神奇之处在于,他不仅可以帮你在微信上制作活动页面,而且还可以帮你侦查到谁偷偷浏览了你的页面(悄悄来,又悄悄走,不

  • ebpf_ebpf需要修改内核吗

    ebpf_ebpf需要修改内核吗eBPF简史BPFBPF的全称是BerkeleyPacketFilter,顾名思义,这是一个用于过滤(filter)网络报文(packet)的架构。过滤(Filter):根据外界输入的规则过滤报文;复制(Copy):将符合条件的报文由内核空间复制到用户空间;?packet报文buffer百度百科在计算机领域,缓冲器指的是缓冲寄存器,它分输入缓冲器和输出缓冲器两种。前者的作用是将外设送来的数据暂时存放,以便处理器将它取走;后者的作用是用来暂时存放处理器送往外设的数据。有了数控缓冲器,

  • IDF – CTF – 牛刀小试

    IDF – CTF – 牛刀小试

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号