关闭

Objective-C 中的 Meta-class 是什么

标签: objective
302人阅读 评论(0) 收藏 举报
分类:

关注的是 Objective-C 中的一个陌生的概念—— meta-class。在 Objective-C 中的每个类都有一个相关联的 meta-class,但是你很少会直接使用 meta-class,他们仍旧保持着神秘的面纱。我们从在运行时创建一个类开始。通过查看 “class pair”,我会解释 meta-class 是什么,同时也会谈谈在 Objective-C 中的对象或者类相关的一些一般主题。
每个对象都有一个类。这是面相对象概念的基础知识,但在 Objective-C 中不是这样,它(译注:class)同样是这个数据的一部分。每个可以被当成对象的数据结构都在恰当的位置有一个指向一个类的指针。

在 Objective-C,一个对象的类由它的 isa 指针决定。isa 指针指向这个对象的 Class。

事实上,在 Objective-C 中的对象的定义看起来像这样:

1
2
3
typedef struct objc_object {
Class isa;
} *id;
这就是说:任何结构体只要以一个指向 Class 结构的指针开始的就可以被当成是 objc_object。

在 Objective-C 中的对象的一个重要的特性是,你可以向它们发送消息:
[@”stringValue”
writeToFile:@”/file.txt” atomically:YES encoding:NSUTF8StringEncoding error:NULL];
你可以这么做是因为,当你向一个 Objective-C 的对象(像这里的 NSCFString)发送消息的时候,runtime 沿着对象的 isa 指针找到了这个对象的 Class(这里是 NSCFString 的类)结构体。 Class 结构体中包含了一个这个类的方法列表和一个指向父类的指针,用于查找继承的方法。

关键点是 Class 结构体中定义了你可以向一个对象发送的消息。

meta-class 是什么?

现在,你可能已经知道,在 Objective-C 中一个 Class 也是一个对象。这就意味着你也可以向一个 Class 发送消息。

1
NSStringEncoding defaultStringEncoding = [NSString defaultStringEncoding];
这里,向 NSString 类发送了 defaultStringEncoding。

可以这么做是因为在 Objective-C 中每个 Class 它自己同样也是个对象。也就是说 Class 结构体必须以 isa 指针开始,然后就可以在二进制兼容(binary compatible)我上面介绍的 objc_object 结构了,接着下一个字段必须是一个指向它的父类的指针(要是类就是基类就是 nil)。

为了让我们在 Class 上调用一个方法,Class 的 isa 指针必须指向一个 Class 结构体,并且那个 Class 结构体必须包含我们可以在那个 Class 上调用的方法的列表。

这就引出了 meta-class 的定义:meta-class 是 Class 对象的类(the meta-class is the class for a Class object)。

简单来说:

当你向一个对象发送消息,就在那个对象的方法列表中查找那个消息。
当你想一个类发送消息,就再那个类的 meta-class 中查找那个消息。
meta-class 是必须的,因为它为一个 Class 存储类方法。每个类都必须有一个唯一的 meta-class,因为每个 Class 都有一个可能不一样的类方法。

meta-class 的类是什么?

meta-class,如之前的 Class,同样是个对象。这就意味着你也可以在它上面调用方法。自然的,这就意味着它也必须有一个类(译注:isa 指针)。

所有的 meta-class 使用它们基类的 meta-class (继承层次中最顶层的 Class 的 meta-class)作为它们自己的类。这就是说所有继承自 NSObject 的类(大部分的类),以 NSObject 的 meta-class 作为自己的 meta-class 的类。

遵循这个规则,所有的 meta-class 使用基类的 meta-class 作为他们的类,任何基类的 meta-class 将会是他们自己(它们的 isa 指向他们自己)。这就是说 NSObject 的 meta-class 的 isa 指针指向它们自己(是自己的一个实例)。

class 和 meta-class 的继承

和 Class 以 super_class 指针指向它的父类的方法一样,meta-class 以 super_class 指针指向 Class 的 super_class 的 meta-class。(译注:这句话有点绕,就是 super-class 一个指向 Class 的父类,一个指向 meta-class 的父类。Class 是一般对象的类型,meta-class 是 Class 的类型。)

进一步来讲,基类的 meta-class 设置 super_class 指针指向基类自己。

这个继承层次的结果就是,所有在这个继承层次中的的实例,类和 meta-class 都继承了基类的层次。

对于所有在 NSObject 层次中的实例,类和 meta-class,这就意味着所有 NSObject 的实例方法都是有效的。对于类和 meta-class,所有 NSObject 的类方法也同样是有效的。

所有这些在字面上相当让人困惑。Greg Parker 已经把实例,类,meta-class 还有他们的超类以非常棒的图解的方式聚合在一起,展示他们是如何在一起工作的。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:215104次
    • 积分:3850
    • 等级:
    • 排名:第8545名
    • 原创:171篇
    • 转载:14篇
    • 译文:1篇
    • 评论:33条
    文章分类
    最新评论