类与元类
Objective-C is a class-based object system. Each object is an instance of some class; the object's isa pointer points to its class. That class describes the object's data: allocation size and ivar types and layout. The class also describes the object's behavior: the selectors it responds to and instance methods it implements.
Objective-C是一个基于类的对象系统。每个对象都是某个类的实例;对象的 isa 指针指向其类。类不但描述其对象的内存分配大小以及变量的类型和布局。而且还描述了对象响应的方法(selectors)以及实现的实例方法。
Ps: 选择器可以理解为方法
The class's method list is the set of instance methods, the selectors that the object responds to. When you send a message to an instance, objc_msgSend() looks through the method list of that object's class (and superclasses, if any) to decide what method to call.
类的方法列表是实例方法的集合,这些实例方法是对象响应的选择器。当你向实例对象发送消息时,objc_msgSend() 会查看该对象的类(及其父类,如果有)的方法列表,以确定要调用的方法。
Each Objective-C class is also an object. It has an isa pointer and other data, and can respond to selectors. When you call a "class method" like [NSObject alloc], you are actually sending a message to that class object.
每个 Objective- C类也是一个对象。它也有一个 isa 指针和其他数据(类的数据结构),并且可以响应方法。当你调用像[NSObject alloc]
的类方法时,实际上是向该类对象发送一条消息。
Since a class is an object, it must be an instance of some other class: a metaclass. The metaclass is the description of the class object, just like the class is the description of ordinary instances. In particular, the metaclass's method list is the class methods: the selectors that the class object responds to. When you send a message to a class - an instance of a metaclass - objc_msgSend() looks through the method list of the metaclass (and its superclasses, if any) to decide what method to call. Class methods are described by the metaclass on behalf of the class object, just like instance methods are described by the class on behalf of the instance objects.
因为类是对象,所以它也一定是其他类的实例,而这个类就是元类。元类是类对象的类(描述),就像类是普通实例的类(描述)一样。此外,元类的方法列表里面都是类方法,类对象都可以调用这些方法。当你向类(元类的实例)发送消息时,objc_msgSend()将查找元类(及其父类,如果有)的方法列表,以确定要调用的方法。类方法由元类代表类对象描述,就像实例方法由类代表实例对象描述一样。
What about the metaclass? Is it metaclasses all the way down? No. A metaclass is an instance of the root class's metaclass; the root metaclass is itself an instance of the root metaclass. The isa chain ends in a cycle here: instance to class to metaclass to root metaclass to itself. The behavior of metaclass isa pointers rarely matters, since in the real world nobody sends messages to metaclass objects.
元类呢?它一直都是元类吗?不。元类是根类的元类的一个实例。根元类本身就是根元类的实例。 isa 链最终以一个循环结束:实例 --> 类 --> 元类 --> 根元类 --> 指向自己
。元类 isa 指针一般很少有问题,因为在现实世界中,没有人会把消息发送给元类对象。
More important is the superclass of a metaclass. The metaclass's superclass chain parallels the class's superclass chain, so class methods are inherited in parallel with instance methods. And the root metaclass's superclass is the root class, so each class object responds to the root class's instance methods. In the end, a class object is an instance of (a subclass of) the root class, just like any other object.
更重要的是元类的父类。元类的父类链与类的父类链平行,因此类方法与实例方法并行继承。根元类的父类是它自己(根元类),因此每个类对象都会响应根类的实例方法(例如 NSObject 类既可以调用其类方法,也可以调用其实例方法)。最后,类对象是根类的实例,就像其他对象一样。
Confused? The diagram may help. Remember, when a message is sent to any object, the method lookup starts with that object's isa pointer, then continues up the superclass chain. "Instance methods" are defined by the class, and "class methods" are defined by the metaclass plus the root (non-meta) class.
困惑?下图可能会有所帮助。请记住,当给任意对象发送消息时,方法查找从该对象的 isa 指针开始,然后沿着父类链一直往下查找。实例方法由类定义,类方法由元类加根类定义(可以理解为:类方法 = 元类的类方法 + NSObject的实例方法)。
class diagram.jpg实例、类、元类以及他们父类之间的关系图
In proper computer science language theory, a class and metaclass hierarchy can be more free-form, with deeper metaclass chains and multiple classes instantiated from any single metaclass. Objective-C uses metaclasses for practical goals like class methods, but otherwise tends to hide metaclasses. For example, [NSObject class] is identical to [NSObject self], even though in formal terms it ought to return the metaclass that NSObject->isa points to. The Objective-C language is a set of practical compromises; here it limits the class schema before it gets too, well, meta.
在真正的计算机科学语言理论中,类和元类的层次结构可以更加自由,并且具有更深的元类链和可以从任何元类实例化出多个类。Objective-C
使用元类来实现类方法等实际目标,但是往往会隐藏元类。例如,[NSObject class]
跟[NSObject self]
是一样的,即使从形式上讲,它也应返回NSObject->isa
指向的元类 。Objective-C
语言其实是一套适用的折中方案;在这里,meta 让它变得更好,同时它也限制了类的模式。