Published on

The isa Pointer in Objective-C

Introduction

In Objective-C, NSObject is the root class for most classes.

@interface NSObject <NSObject> {
    Class isa  OBJC_ISA_AVAILABILITY;
}

It has an isa property of type Class. What is isa? And what is Class?

isa

The definition of Class in <objc.h>:

#if !OBJC_TYPES_DEFINED
/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;

/// Represents an instance of a class.
struct objc_object {
    Class isa  OBJC_ISA_AVAILABILITY;
};

/// A pointer to an instance of a class.
typedef struct objc_object *id;
#endif

Class is a pointer to an objc_class struct, and id is a pointer to an objc_object struct.

Now let's look at the definition of objc_class in <runtime.h>:

struct objc_class {
    Class isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
	Class super_class; // pointer to the superclass
	const char *name; // class name
	long version; // class version info, default 0; can be read/written via class_setVersion and class_getVersion
	long info; // some flag bits, e.g. CLS_CLASS (0x1L) means a regular class containing instance methods and member variables; CLS_META (0x2L) means a metaclass containing class methods
	long instance_size ; // the size of the class's instance variables (including those inherited from superclasses)
	struct objc_ivar_list *ivars; // used to store the address of each member variable
	struct objc_method_list **methodLists; // depends on the info flag bits; CLS_CLASS (0x1L) stores instance methods, CLS_META (0x2L) stores class methods
	struct objc_cache *cache; // pointer to the most recently used method, for performance optimization
	struct objc_protocol_list *protocols; // protocols that the class conforms to
#endif
  • isa: A pointer of type Class. Every instance object has an isa pointer pointing to its class, and the Class itself also has an isa pointer pointing to its metaclass. The metaclass stores the list of class methods. When a class method is called, the runtime first looks for the implementation in the class itself; if not found, the metaclass searches its parent class. Note that a metaclass (metaclass) is itself a class and therefore also an object. Metaclasses also have isa pointers, and those ultimately point to a root metaclass (root metaclass). The root metaclass's isa pointer points to itself, forming a closed loop.
  • super_class: The superclass. If this class is already the topmost root class, this is NULL.
  • version: Class version info, default 0.
  • info: Some bit flags used at runtime.
  • instance_size: The size of the class's instance variables.
  • ivars: An array of member variables.
struct objc_ivar_list {
    int ivar_count;
#ifdef __LP64__
    int space;
#endif
    /* variable length structure */
    struct objc_ivar ivar_list[1];
};
  • methodLists: An array of method definitions.
struct objc_method_list {
    struct objc_method_list *obsolete;

    int method_count;
#ifdef __LP64__
    int space;
#endif
    /* variable length structure */
    struct objc_method method_list[1];
};
  • objc_cache: Points to recently used methods, used to optimize method dispatch.
  • protocols: An array of protocols.

An additional note on metaclasses (metaclass):

Core rule: An instance object's isa points to its class; the class's isa points to its metaclass.

In plain terms: instance methods are recorded in the class method-list; class methods are recorded in the metaClass. That is, the information for an instance-object lives in the class-object, and the information for the class-object lives in the metaClass.

The inheritance relationships for class instance variables: Inheritance Diagram

Every object is fundamentally an instance of a class. The class defines the list of member variables and methods. An object points to its class via the object's isa pointer.

Every class is fundamentally an object — a class is actually an instance of its metaclass (metaclass). The metaclass defines the list of class methods. A class points to its metaclass via the class's isa pointer.

All metaclasses ultimately inherit from a root metaclass, whose isa pointer points to itself, forming a closed loop.