I always have a vague understanding of the nature of ios OC/Swift classes. I seem to know but not very clear. I spent some time on the weekend sorting out notes.

Runtime.h objC_class definition (Objc2 has been deprecated, this version is also the source code used by the most, need to be alert!)

#if ! OBJC_TYPES_DEFINED /// An opaque type that represents a method in a class definition. typedef struct objc_method *Method; /// An opaque type that represents an instance variable. typedef struct objc_ivar *Ivar; /// An opaque type that represents a category. typedef struct objc_category *Category; /// An opaque type that represents an Objective-C declared property. typedef struct objc_property *objc_property_t; struct objc_class { Class isa OBJC_ISA_AVAILABILITY; #if ! __OBJC2__ Class super_class OBJC2_UNAVAILABLE; const char *name OBJC2_UNAVAILABLE; long version OBJC2_UNAVAILABLE; long info OBJC2_UNAVAILABLE; long instance_size OBJC2_UNAVAILABLE; struct objc_ivar_list *ivars OBJC2_UNAVAILABLE; struct objc_method_list **methodLists OBJC2_UNAVAILABLE; struct objc_cache *cache OBJC2_UNAVAILABLE; struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; #endif } OBJC2_UNAVAILABLE; /* Use `Class` instead of `struct objc_class *` */ #endifCopy the code

(does seem straightforward, but there is no use) — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — – gold line — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

Objc-private. h objc-private.h objc-private.h objc-private.h

typedef struct objc_class *Class;
typedef struct objc_object *id;
Copy the code

Objc-runtime-new. h defines objc_class as follows:

struct objc_class : objc_object { // Class ISA; Class superclass; cache_t cache; // formerly cache pointer and vtable class_data_bits_t bits; // class_rw_t * plus custom rr/alloc flags class_rw_t *data() { return bits.data(); }... }; // struct swift_class_t: objc_class {uint32_t flags; uint32_t instanceAddressOffset; uint32_t instanceSize; uint16_t instanceAlignMask; uint16_t reserved; uint32_t classSize; uint32_t classAddressOffset; void *description; / /... void *baseAddress() { return (void *)((uint8_t *)this - classAddressOffset); }};Copy the code

A class must have a list of member variables, a list of attributes, a list of protocols, where are they? In Objc2.0, the storage location is in class_rw_T, where class_ro_T is understood to be the part of the general definition of the class, and class_rw_t contains the part of the general definition and the part of the dynamic method load.

struct class_rw_t { uint32_t flags; uint32_t version; const class_ro_t *ro; method_array_t methods; property_array_t properties; protocol_array_t protocols; Class firstSubclass; Class nextSiblingClass; char *demangledName; . }; struct class_ro_t { uint32_t flags; uint32_t instanceStart; uint32_t instanceSize; #ifdef __LP64__ uint32_t reserved; #endif const uint8_t * ivarLayout; const char * name; method_list_t * baseMethodList; protocol_list_t * baseProtocols; const ivar_list_t * ivars; const uint8_t * weakIvarLayout; property_list_t *baseProperties; method_list_t *baseMethods() const { return baseMethodList; }};Copy the code

Where is the classification? And I need it to be more productive? Objc-runtime-new.h objc-Runtimenew.h objc-Runtimenew.h objc-Runtimenew.h objc-Runtimenew.h objc-Runtimenew.h

static void addUnattachedCategoryForClass(category_t *cat, Class cls, 
                                          header_info *catHeader)
{
    runtimeLock.assertWriting();

    // DO NOT use cat->cls! cls may be cat->cls->isa instead
    NXMapTable *cats = unattachedCategories();
    category_list *list;

    list = (category_list *)NXMapGet(cats, cls);
    if (!list) {
        list = (category_list *)
            calloc(sizeof(*list) + sizeof(list->list[0]), 1);
    } else {
        list = (category_list *)
            realloc(list, sizeof(*list) + sizeof(list->list[0]) * (list->count + 1));
    }
    list->list[list->count++] = (locstamped_category_t){cat, catHeader};
    NXMapInsert(cats, cls, list);
}

struct locstamped_category_t {
    category_t *cat;
    struct header_info *hi;
};

struct locstamped_category_list_t {
    uint32_t count;
#if __LP64__
    uint32_t reserved;
#endif
    locstamped_category_t list[0];
};

struct category_t {
    const char *name;
    classref_t cls;
    struct method_list_t *instanceMethods;
    struct method_list_t *classMethods;
    struct protocol_list_t *protocols;
    struct property_list_t *instanceProperties;

    method_list_t *methodsForMeta(bool isMeta) {
        if (isMeta) return classMethods;
        else return instanceMethods;
    }

    property_list_t *propertiesForMeta(bool isMeta) {
        if (isMeta) return nil; // classProperties;
        else return instanceProperties;
    }
};

Copy the code

I saw my old friend again:

    struct method_list_t *instanceMethods;
    struct method_list_t *classMethods;
    struct protocol_list_t *protocols;
    struct property_list_t *instanceProperties;
Copy the code

At this point, we basically know the structure of objC_class, corresponding member variables, properties, methods, and stored variables of the protocol list; And category storage;