翻譯參考鏈接:[objc 解釋]:類和元類
英文原文:[objc explain]: Classes and metaclasses
objc系列文章
http://www.sealiesoftware.com/blog/archive/index.html
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.
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.
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.
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.
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.
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.
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.
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.
下面是翻譯:
Object-C 是基于類的對象系統(tǒng)。每一個對象都是一些類的實例十办;這個對象的 isa 指針指向它所屬的類秀撇。該類描述這個對象的數(shù)據(jù)信息:內(nèi)存分配大小(allocation size)和實例變量的類型(ivar types )與布局(layout)。這個類也描述了對象的行為:它能夠響應的選擇器(selectors)和它實現(xiàn)的實例方法(instance methods)向族。
類的方法列表是一個實例方法的集合(instance methods)呵燕,是對象響應的選擇器(selectors)。當你向一個實例發(fā)送一條消息炸枣,objc_msgSend()
查詢對象所屬類(和它的父類虏等,如果有)的方法列表,去決定調(diào)用哪個方法适肠。
每個 Object-C 類也是一個對象霍衫。它有一個 isa 指針和其他數(shù)據(jù),并且可以響應選擇器侯养。當你調(diào)用一個“類方法”敦跌,例如:[NSObject alloc],你實際上是向類對象發(fā)送了一條消息。
由于一個類是一個對象柠傍,它肯定也是其他類的實例麸俘,這個類是元類(metaclass)。元類是關于類對象的描述惧笛,就像類是普通實例對象的描述一樣从媚。實際上,元類的方法列表正是類方法(該類對象響應的選擇器)患整。當你向一個類(元類的實例)發(fā)送消息拜效,objc_msgSend()查詢元類(和它的父類,如果有)的方法列表各谚,去決定調(diào)用哪個方法紧憾。元類為類對象描述類方法,就像類為實例對象描述實例方法一樣昌渤。
元類赴穗?元類鏈是一直向下的嗎?不是膀息,一個元類是根元類的實例般眉;根元類是它自身的實例。isa 指針鏈以一個環(huán)結束:實例指向類-指向元類-指向根元類-到自身履婉。元類的 isa 指針并不重要煤篙,因為在現(xiàn)實世界中,沒人會向元類對象發(fā)送消息毁腿。
元類的父類就要更重要了辑奈。元類的父類鏈平行于類的父類鏈,因此類方法跟實例方法一樣被繼承已烤。并且根元類的父類是根類鸠窗,因此每個類對象都響應根類的實例方法。最后胯究,一個類對象就像其他對象一樣是根類的實例(或子類)稍计。
暈了吧?這個圖肯定會幫助你裕循。記住臣嚣,當一個消息被發(fā)送到任何對象,都會從對象的 isa 指針開始尋找應該調(diào)用的方法剥哑,然后繼續(xù)沿著父類鏈向上尋找硅则。“實例方法”被類定義株婴,“類方法”被元類和根類(非元類)定義怎虫。
在合理的電腦科學語言理論中,一個類和元類的層次結構可以是更自由的形式,像更深的元類鏈以及任何單一的元類實例化多個類大审。Object-C 使用元類實現(xiàn)了類方法這樣的實際目的蘸际,但在其他情況下趨向于隱藏元類。例如徒扶,[NSObject class]等價于[NSObject self]粮彤,盡管按正常的理解它應該返回 NSObject->isa 指向的元類。Object-C 語言有一些實際情況的妥協(xié)姜骡,在這里驾诈,它不能得到類的實際結構,元類溶浴。