博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
类和元类
阅读量:6445 次
发布时间:2019-06-23

本文共 1383 字,大约阅读时间需要 4 分钟。

本文翻译自苹果公司 runtime 源码的维护者 Greg Parker 的 blog:

Objective-C 是一门基于类的对象系统,每一个对象都是某个类的实例;对象的 isa 指针指向它的类。该类描述对象的数据:数据占用的空间,变量的类型和布局等。该类也描述对象的一些行为:对象可以响应的选择器(selector)和对象实现的实例方法。

(译者注:面向对象的含义,类是一类事物的共有特性的描述,比如:“人”类中的“姓名”,“年龄”等属性,“吃饭”、“喝水”等行为,所有的人都具备,所以类是对象的属性和行为的描述)

类中的方法列表是实例方法(对象可以响应的选择器)的集合。当你向对象发送一个消息的时候,objc_msgSend() 会通过查询该对象的类(和父类)中的方法列表来决定调用什么方法。

每一个 Objective-C 的类也是一个对象。它也有自己的 isa 指针、数据以及它可以响应的选择器。当你调用一个类方法的时候,例如 [NSObject alloc],实际上你是向这个类对象(NSObject)发送了一条消息。

由于类也是对象,那么它一定也是某一个类的实例,即元类。就像类是普通对象的描述一样,元类是类对象的描述。值得一提的是,元类的方法列表中存的是类方法:类对象可以响应的选择器。当你向一个类对象(元类的实例)发送消息(调用类方法)的时候,objc_msgSend() 会通过查询该类对象的元类(和父元类)中的方法列表来决定调用什么方法。就像实例方法是类对对象的行为的描述一样,类方法是元类对类对象的行为的描述(有点拗口)。

那么元类呢?是最底层的吗?不,元类是根类(NSObject)的元类的实例,根元类是根元类自己的实例,isa 指针链在一个循环处结束:对象 -> 类对象 -> 元类 -> 根元类 -> 根元类(-> 指向)。元类的 isa 指针的行为很少受到关注,因为在现实中没有人可以向元类对象发送消息。

那么元类的父类是谁呢?元类的父类链平行于类的父类链,所以类方法的继承关系和实例方法是一样的。并且根元类的父类是根类(即,NSObject 的元类的父类是它自己)(划重点),所以每一个类对象都可以响应根类的实例方法(即,根类的实例方法其实也是每一个类的类方法)。所以,类对象也和其他对象一样,都是根类的实例,但是类对象也是根类的子类。

是不是很迷惑,上面这张图可以帮助到你!请记住,当你向一个对象发消息的时候,方法的查找会从对象的 isa 指针开始,然后继续顺着父类链查找。“实例方法”在类中定义,“类方法”在元类和根类中定义。

(译者注:方法列表中并没有什么值来规定某一个方法是类方法还是实例方法,一个对象能通过 isa 链和父类链找到的那个方法就是它能响应的方法,所以,类对象可以通过根元类的父类指针找到根类中的方法,那么它就可以响应这个方法,即使你认为根类中存的应该是“实例方法”。)

在正式的计算机科学语言中,类和元类的继承制度是更自由的形式,比如,更深层的元类链和很多类是某单一元类的实例。OC相对于 使用元类实现像类方法这样的实际目标,更趋向于隐藏元类。例如: 其实 [NSObject class][NSObejct self] 是等价的,即使,理论上它应该返回 NSObject -> isa 指向的的元类。

转载地址:http://grpwo.baihongyu.com/

你可能感兴趣的文章
我的友情链接
查看>>
ClassLoader
查看>>
COM 互操作 - 第一部分”示例
查看>>
Oracle中随机抽取N条记录
查看>>
自动安装
查看>>
Javascript生成随机数
查看>>
java中关于this的学习笔记
查看>>
sql打印了,但数据库木有数据处理
查看>>
机器学习面试之各种混乱的熵(一)
查看>>
zabbix3.0.4安装部署文档(三)----添加监控主机
查看>>
抓鸡 抓服务器 1433 3306 全自动效率抓鸡
查看>>
Linux常用软件
查看>>
Java下数字类型的转换
查看>>
DNS原理及DNS服务器的建立(主从)
查看>>
我的友情链接
查看>>
mongodb的安装及主从复制
查看>>
VMware虚拟化技术培训(10) 桌面虚拟化之二
查看>>
Win7旗舰版中的IIS配置asp.net的运行环境
查看>>
Stimulsoft Reports.Net基础教程(八):创建列式报表②
查看>>
Maven
查看>>