认识Runtime1

认识Runtime1

什么是id?

id在objc.h中的定义如下:

typedef struct objc_object *id;

那么什么是objc_object呢?
objc_object在objc.h中的定义如下:

struct objc_object {
    Class isa;
}

这个时候我们知道Objective-C中的object最后被转化成了C的结构体,而在这个struct种只有一个isa指针,指向它的类别Class.
那么什么是Class 呢?
在objc.h中定义如下:

typedef struct objc_class *Class;

我们可以看懂Class本身指向的也是一个C的struct objc_class.
我们看一下runtime.h中objc_class的定义如下:

struct objc_class {
    Class isa                       OBJC_ISA_AVAILABILITY,
#if !_OBJC@_
    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;
  • isa指向类的本身
  • cache:用于缓存最近使用的方法。一个接收者对象接收到一个消息时,它会根据isa指针去查找能够响应这个消息的对象。实际中,对象只有一部分方法是常用的,很多方法其实根本不用。这样,如果每次消息来时,我们都是在methodLists中遍历一遍,性能肯定会很差。这时cache就盼上用场了。每次调用过一个方法之后,这个方法就会被缓存到cache列表中,下次调用的时候runtime就会优先去cache中查找,如果没有才去methodLists中查找方法,这样对于经常用到的方法的调用,提高了调用效率。

在OC中,一切都是对象,Class在设计的本身也是一个对象。而这个Class对象对应的类,我们叫他Meta Class.即Class结构体中的isa指向就是他的元类。

Meta Class

我们可以把Meta Class理解为一个Class对象的Class.简单的说:

  • 当我们发送一个消息给一个NSObject对象时,这条信息会在对象的类方法列表里面查找。
  • 当我们发送一个消息给一个类是,这条消息会在Meta Class的方法列表里查找。

附:

参考自:

时间: 2024-11-18 00:24:38

认识Runtime1的相关文章

“前.NET Core时代”如何实现跨平台代码重用 ——程序集重用

除了在源代码层面实现共享("前.NET Core时代"如何实现跨平台代码重用 --源文件重用)之外,我们还可以跨平台共享同一个程序集,这种独立于具体平台的"中性"程序集通过创建一种名为"可移植类库(PCL: Portable Class Library)"项目来实现.为了让读者朋友们对PCL的实现机制具有充分的认识,我们先来讨论一个被我称为"程序集动态绑定"的话题. 目录 一.何谓程序集动态绑定? 二.程序集一致性 三.程序集

LINQ To SQL在N层应用程序中的CUD操作、批量删除、批量更新

原文:LINQ To SQL在N层应用程序中的CUD操作.批量删除.批量更新 0. 说明     Linq to Sql,以下简称L2S.    以下文中所指的两层和三层结构,分别如下图所示:       准确的说,这里的分层并不是特别明确:(1) 生成的DataContext(Linq t0 SQL Runtime)和Entity是放在一个文件中的,物理上不能切割开来:上图只是展示逻辑上的结构.(2) 拿上图右边的三层结构来说,鉴于第(1)点,UI层就可以跨越BusinessLogic层,直接

Dockerfile最佳实践(一)

本文讲的是Dockerfile最佳实践(一),[编者的话]本文是Docker入门教程第三章-DockerFile的进阶篇,作者主要介绍了缓存.标签.端口以及CMD与ENTRYPOINT的最佳用法,并通过案例分析了注意事项,比如我们应该使用常用且不变的Dockerfile开头.通过-t标记来构建镜像.勿在Dockerfile映射公有端口等等. Dockerfile使用简单的语法来构建镜像.下面是一些建议和技巧以帮助你使用Dockerfile. 1.使用缓存 Dockerfile的每条指令都会将结果

java怎么结束执行ba,t终止虚拟机的运行但是不会终止服务器

问题描述 做了一个系统,后台算法用java实现,用runtime去执行外部程序,当外部程序出现死循环时怎么结束这个死循环,关闭执行外部程序,但是同时不杀死在运行的服务器,系统照常运行..求指导 解决方案 解决方案二:用runtime去执行taskkill/im要结束的进程名称就可以了.解决方案三: importjava.io.BufferedReader;importjava.io.File;importjava.io.FileWriter;importjava.io.IOException;i