[iOS] class, metaclass, parent class relationship

foreword

Recently, in the process of learning OC, I was asked by seniors aboutisKindOfClass 和 isMemberOfClassBefore distinguishing the difference between the two, the author thinks that it is necessary to understand the relationship between class, metaclass, and parent class .
At the same time, there are actually a lot of information on the relationship between classes, metaclasses, and parent classes on the Internet . The author only records the learning process here.

import

We all know that our isKindOfClass and isMemberOfClass have both instance methods and class methods, adding up to a total of four methods

Here we first need to understand80% of the bottom layer of OC is C language, and the objects that are usually created (classes also belong to objects, class objects) are converted into structures in the bottom C language

Source code for classes and objects

Here we give the definition of class and object source code:

Our class is essentially a pointer to a structure:

typedef struct objc_class *Class;  
struct objc_class {
    
      
    Class isa;  
    Class super_class;  
    const char *name;  
    long version;  
    long info;  
    long instance_size;  
    struct objc_ivar_list *ivars;  
    struct objc_method_list **methodLists;  
    struct objc_cache *cache;  
    struct objc_protocol_list *protocols;  
}; 

Let's look at the definition of our object again

insert image description here
We have named our Class with typedef in the code of our class definition. Class is essentially a structure pointer, and our isa pointer points to the class pointed to by this object.

Our use of metaclasses should be learned later when we learn the message sending mechanism of iOS, and we will add it later here. Because the author has not studied this part of knowledge, so here is a direct reference to the definition of seniors:

An OC class is actually an object, and an object must have a class to which it belongs, which means that a class must also have an isa pointer pointing to the class to which it belongs. So what is a class of a class? It is what we call a metaclass (MetaClass), so a metaclass is the class to which a class belongs.

Similarly, our metaclass is also a class, so it should also have its own class. Here is a well-known OC diagram: Here
insert image description here
are a few English words we need to understand.
The first is Meta: it means that the current class belongs to the metaclass
followed by isa: we mentioned above, isaIt is actually a pointer to the class to which the current object belongs

In this way, we can summarize the basic relationship between our class, metaclass and parent class:

isa-oriented

  1. The class of the instance object is actually its class, and our instance object is the Instance of Subclass in the figure.
    Next, our isa points to our class, so continue to study the class to which our class belongs.
  2. As can be seen from the figure, the class of our class actually points to our metaclass.
  3. Next, let's look at our metaclasses. The classes of all our metaclasses are actually root metaclasses . This is understood in the author's reference materials, because almost all classes in our OC are subclasses of NSObject, so our root metaclasses can also be considered as our NSObject metaclasses.
  4. Then we look at the dotted line of the root metaclass in the figure. The class to which the root metaclass belongs points to itself.

superClass oriented

Our superClass here points to the parent class of our class. It is actually easier to understand here. The metaclass is the same as our class, and its parent class is layered up, unlike the class to which the metaclass belongs. All point to our root metaclass

The only thing to note here is that the parent class of our root metaclass is our root class, which can also be understood as the NSObject class. The parent class of the NSObject class is nil.

We use our code to check the correctness of our conclusion:

/// 实例化
    NSObject *obj = [[NSObject alloc]init];
    Person *person = [[Person alloc]init];
    Student *student = [[Student alloc]init];
    /// 获取实例对象的isa。即类
    Class Object = object_getClass(obj);
    Class Person = object_getClass(person);
    Class Student = object_getClass(student);
    /// 通过名字获取类
    Class Object1 = objc_getClass("NSObject");
    Class Person1 = objc_getClass("Person");
    Class Student1 = objc_getClass("Student");
    /// 获取类的父类
    Class ObjectSup = class_getSuperclass(Object1);
    Class PersonSup = class_getSuperclass(Person1);
    Class StudentSup = class_getSuperclass(Student1);
    /// 获取类的元类
    Class ObjectMeta = objc_getMetaClass("NSObject");
    Class PersonMeta = objc_getMetaClass("Person");
    Class StudentMeta = objc_getMetaClass("Student");
    /// 获取元类的父类
    Class ObjectMetaSup = class_getSuperclass(ObjectMeta);
    Class PersonMetaSup = class_getSuperclass(PersonMeta);
    Class StudentMetaSup = class_getSuperclass(StudentMeta);
    /// 通过类的isa获取Class ,实际就是元类,所以PersonMeta1的地址和PersonMeta是一样的,StudentMeta1的地址和StudentMeta是一样的。
    Class ObjectMeta1 = object_getClass(Object1);
    Class PersonMeta1 = object_getClass(Person1);
    Class StudentMeta1 = object_getClass(Student1);
    /// 通过元类的isa获取Class, 实际都是根元类,所以PersonMetaIsa和StudentMetaIsa,ObjectMetaIsa的地址是一样的
    Class ObjectMetaIsa = object_getClass(ObjectMeta);
    Class PersonMetaIsa = object_getClass(PersonMeta);
    Class StudentMetaIsa = object_getClass(StudentMeta);

Compilation result after adding breakpoints:
insert image description here

Materials referenced in this article:
iOS popular understanding of the relationship between classes, parent classes, and metaclasses
[iOS development] summary of the relationship between classes, parent classes, and metaclasses

Guess you like

Origin blog.csdn.net/weixin_72437555/article/details/130691020