Class objc_allocateClassPair(Class superclass, constchar *name, size_t extraBytes) { Class cls, meta;
rwlock_writer_t lock(runtimeLock);
// Fail if the class name is in use. // Fail if the superclass isn't kosher. if (getClass(name) || !verifySuperclass(superclass, true/*rootOK*/)) { returnnil; }
// Allocate new classes. cls = alloc_class_for_subclass(superclass, extraBytes); meta = alloc_class_for_subclass(superclass, extraBytes);
// fixme mangle the name if it looks swift-y? objc_initializeClassPair_internal(superclass, name, cls, meta);
return cls; }
从上面的代码中我们可以很明显的看出:
1 2
cls = alloc_class_for_subclass(superclass, extraBytes); meta = alloc_class_for_subclass(superclass, extraBytes);
cls和meta的创建方法和参数完全一致!
怎么获取一个类的MetaClass
objc_getMetaClass(const char * _Nonnull name)
我们来看一下这个方法的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Class objc_getMetaClass(constchar *aClassName) { Class cls;
if (!aClassName) return Nil;
cls = objc_getClass (aClassName); if (!cls) { _objc_inform ("class `%s' not linked into application", aClassName); return Nil; }
Metaclasses in Objective-C are almost the same as those in Smalltalk-80—not surprising since Objective-C borrows a lot from Smalltalk. Like Smalltalk, in Objective-C, the instance variables and methods are defined by an object's class. A class is an object, hence it is an instance of a metaclass.(OC中的Metaclasses 基本上和Smalltalk-80相同,鉴于OC从Smalltalk中借鉴了很多因此这并不令人干到奇怪。类似Smalltalk 在OC中实例的变量和方法被定义在对象的类中,class也是一个对象,于是class是mataclass的一个实例。)
Like Smalltalk, in Objective-C, class methods are simply methods called on the class object, hence a class's class methods must be defined as instance methods in its metaclass. Because different classes can have different sets of class methods, each class must have its own separate metaclass. Classes and metaclasses are always created as a pair: the runtime has functions objc_allocateClassPair() and objc_registerClassPair() to create and register class-metaclass pairs, respectively.(类似Smalltalk,在OC中类方法通过类对象调用,于是一个类的类方法必须在metaclass中以实例方法的形式定义。因为不同的类可以后不同的类方法集合,每一个类必须有自己独立的metaClass。Class和class-metaClass一起被创建和注册)
There are no names for the metaclasses; however, a pointer to any class object can be referred to with the generic type Class (similar to the type id being used for a pointer to any object). (metaClass没有名字,然而,指向任何类对象的指针可以用泛型类型引用)(类似id可以指向所有的对象)
Because class methods are inherited through inheritance, like Smalltalk, metaclasses must follow an inheritance scheme paralleling that of classes (e.g. if class A's parent class is class B, then A's metaclass's parent class is B's metaclass), except that of the root class.(因为,类方法通过继承获取,类似Smalltalk,元类必须遵循与类类似的继承方案
Unlike Smalltalk, the metaclass of the root class inherits from the root class (usually NSObject using the Cocoa framework) itself. This ensures that all class objects are ultimately instances of the root class, so that you can use the instance methods of the root class, usually useful utility methods for objects, on class objects themselves.(与Smalltalk不同,根类的metaclass继承自根类本身,这就确保了所有的类对象都是根类的对象。以便您可以使用根类的实例方法,通常是对象的有用实用工具方法,以及类对象本身。)
Since metaclass objects do not behave differently (you cannot add class methods for a metaclass, so metaclass objects all have the same methods), they are all instances of the same class—the metaclass of the root class (unlike Smalltalk). Thus, the metaclass of the root class is an instance of itself. The reason for this is that all metaclasses inherit from root class; hence, they must inherit the class methods of the root class. (由于元类对象行为不同(你不能为元类添加类方法,所以元类对象都有相同的方法),它们都是同一类的实例 - 根类的元类(与Smalltalk不同)因此,根类的元类是它自己的一个实例。原因是所有元类都继承自根类;因此,他们必须继承根类的类方法。)