in iOS ~ read.

Conclusion of objective-C structure

The isa pointer of Instance and Class

  • Firstly, let's have a look at the struct objc_class * of Class, objc_class inherits from objc_object which only have a isa.
//Class is in effect a struct pointer of (objc_class *)
typedef struct objc_class *Class;  
//The struct objc_class
struct objc_class : objc_object {  
    Class superclass;
    cache_t cache;
    class_data_bits_t bits;
    class_rw_t *data() { 
    void setData(class_rw_t *newData) {
    //many set/get methods...
struct objc_object {  
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
struct class_rw_t {  
    // Be warned that Symbolication knows the layout of this structure.
    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;
    uint32_t index;
//some other methods ...
  • In the struct code above, we can see that methods, propertys, protocols and some other values are stored in the class's struct.

  • Here is a picture how a class's superclass pointer point to its superclass. Class Structure

  • Take a look at initialization process of NSObject:

+ (id)alloc {
    return _objc_rootAlloc(self);
id _objc_rootAlloc(Class cls)  
    return callAlloc(cls, false/*checkNil*/, true/*allocWithZone*/);
static ALWAYS_INLINE id  
callAlloc(Class cls, bool checkNil, bool allocWithZone=false)  
//This command is to check (checkNil && !cls)'s result which tell complier the result is more possible to be false;
    if (slowpath(checkNil && !cls)) return nil;
#if __OBJC2__
// hasCustomAWZ() method means class or superclass has default alloc/allocWithZone: implementation, note this is is stored in the metaclass
    if (fastpath(!cls->ISA()->hasCustomAWZ())) {
// FAST_ALLOC means
//   FAST_HAS_CXX_CTOR is set
//   FAST_REQUIRES_RAW_ISA is not set
//   FAST_SHIFTED_SIZE is not zero
// FAST_ALLOC does NOT check FAST_HAS_DEFAULT_AWZ because that bit is stored on the metaclass.
        if (fastpath(cls->canAllocFast())) {
            bool dtor = cls->hasCxxDtor();
            id obj = (id)calloc(1, cls->bits.fastInstanceSize());
            if (slowpath(!obj)) return callBadAllocHandler(cls);
            obj->initInstanceIsa(cls, dtor);
            return obj;
        else {
            // Has ctor or raw isa or something. Use the slower path.
            id obj = class_createInstance(cls, 0);
            if (slowpath(!obj)) return callBadAllocHandler(cls);
            return obj;
    if (allocWithZone) return [cls allocWithZone:nil];
    return [cls alloc];
//The slow Path: class_createInstance
//The fast path: initInstanceIsa, return value type is objc_object;
inline void  
objc_object::initInstanceIsa(Class cls, bool hasCxxDtor)  
    assert(hasCxxDtor == cls->hasCxxDtor());
    initIsa(cls, true, hasCxxDtor);
//Here is the struct of objc_object
struct objc_object {  
    isa_t isa;
//other methods
  • Here is a image!

Instance' and class' method calling trace

  • There is a classical image: conclusion of instance and class isa trace

  • All in all:

    • Instance's isa point to its Class
    • Class' isa point to its meta-class
    • Meta-class' isa point to its root class' meta-class.
    • Class' superclass pointer point to its superclass' Class. If Class have no superclass, it's superclass point to nil.
    • Meta-class superclass point to its superclass' meta-class.
    • The superclass of root class' meta-class point to root class' Class.
  • Instance call trace
    • Instance can use its isa to find its' Class ßand check if the method is exist int its Class's methodList, and then check the superclass if the method not exist.
  • Class call trace
    • Class can use its isa find meta-class, it will contine find its superclass via superclass pointer if the method doesn't exist.


comments powered by Disqus