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;