Objective-C Runtime

Understanding the Dynamic Features of Objective-C

Objectives

Understand the basics of Objective-C runtimes, its types and its features

Gain understanding of various Objective-C runtime methods

Dynamically create and modify objects at runtime

Understand associative reference methods and their usage

Understanding Objective-C selectors and messaging

Introduction to Objective-C Runtimes

The Objective-C runtime is a runtime library, written mainly in C & Assembler. It provides the necessary infrastructure for message passing, method dispatch, dynamic method resolution, introspection, and other runtime operations.

Objective-C has two main runtimes: the "Classic" runtime and the "Modern" runtime.

1. Classic Objective-C Runtime

Based on the C language, it provides the foundation for object-oriented programming in Objective-C. Key features include dynamic method resolution and message passing — allowing objects to respond to messages even if the corresponding method is not defined at compile time.

2. Modern Objective-C Runtime

Introduced with Objective-C 2.0, it retains all Classic features and adds automatic property synthesis via @property, automatic reference counting (ARC), associated objects, and faster message dispatch.

Key Runtime Features

Messaging

Objects communicate by sending messages. The runtime handles dispatch, determining the appropriate method based on the class hierarchy.

Method Swizzling

Change the implementation of a method dynamically at runtime — useful for overriding, extending, or intercepting method calls.

Dynamic Method Resolution

Objects can respond to messages even if the method isn't defined at compile time. Methods can be added dynamically using forwarding.

Introspection

Inspect and manipulate classes and objects dynamically — retrieve class info, create classes, add methods, and modify instance variables at runtime.

Associated Objects

Associate arbitrary data with an object dynamically — add custom properties to existing classes without subclassing.

Protocol Support

The runtime handles protocol conformance checking and dynamically adding or removing protocol support from classes.

NSObject Methods

The NSObject class is the root class of most Objective-C class hierarchies. It provides essential methods inherited by all Objective-C classes.

init & dealloc

init is the designated initializer — sets initial state. dealloc is called during deallocation for cleanup like releasing retained resources.

copy & mutableCopy

copy creates an immutable shallow copy. mutableCopy creates a mutable deep copy, copying referenced objects too.

isEqual: & hash

isEqual: compares object equality based on properties. hash returns an integer hash value used in collections like NSSet and NSDictionary.

description & debugDescription

description returns a string representation for logging. debugDescription provides more detailed info for debugging purposes.

@interface Person : NSObject @property (nonatomic, strong) NSString *name; @property (nonatomic, assign) NSInteger age; @end - (BOOL)isEqual:(id)object { if (self == object) return YES; if (![object isKindOfClass:[Person class]]) return NO; Person *other = (Person *)object; return [self.name isEqualToString:other.name] && self.age == other.age; }

Runtime Methods

Runtime methods provide a way to introspect and manipulate classes, methods, and properties at runtime. They enable dynamic behavior and flexibility.

class_getName & class_getSuperclass

Retrieve the name or superclass of a class dynamically at runtime.

method_getName & method_getTypeEncoding

Retrieve the selector name or type encoding of a method at runtime.

const char *className = class_getName([Person class]); Class superclass = class_getSuperclass([Person class]); // Dynamically add a method SEL selector = @selector(greet); IMP imp = imp_implementationWithBlock(^{ NSLog(@"Hello from dynamic method!"); }); class_addMethod([Person class], selector, imp, "v@:");

Class Definition Methods

These methods allow dynamic class creation and modification at runtime — adding methods, properties, and instance variables on the fly.

objc_allocateClassPair & objc_registerClassPair

Create a new class at runtime and register it with the Objective-C runtime system. Enables dynamic class creation.

class_addMethod & class_replaceMethod

Dynamically add new methods or replace existing implementations in a class at runtime.

// Create a new class at runtime Class newClass = objc_allocateClassPair( [MyClass class], "NewClass", 0 ); // Add a method void (^block)(id, SEL) = ^(id self, SEL _cmd) { NSLog(@"New Method"); }; class_addMethod(newClass, @selector(newMethod), imp_implementationWithBlock(block), "v@:"); // Register and use objc_registerClassPair(newClass); id obj = [[newClass alloc] init]; [obj performSelector:@selector(newMethod)];

Associative References

Associative references let you attach additional objects to existing objects at runtime using a unique key — without subclassing or modifying the original class.

// Attach custom data NSNumber *age = @(30); objc_setAssociatedObject(person, @"age", age, OBJC_ASSOCIATION_RETAIN); // Retrieve it NSNumber *retrieved = objc_getAssociatedObject( person, @"age" ); // Remove all associations objc_removeAssociatedObjects(person);

Selectors

A selector is a way to refer to a specific method — essentially the method name with argument and return type info. Selectors enable dynamic method invocation at runtime.

// Create selectors SEL sel1 = NSSelectorFromString(@"doSomething"); SEL sel2 = @selector(doSomethingWithParam:); // Get implementation IMP imp = class_getMethodImplementation( [MyClass class], sel1 ); // Method swizzling Method m1 = class_getInstanceMethod(cls, sel1); Method m2 = class_getInstanceMethod(cls, sel2); method_exchangeImplementations(m1, m2);

Objective-C Messaging

Messaging is the core dispatch mechanism. When a message is sent to an object, the runtime resolves the method and executes its implementation.

Message Forwarding

When an object doesn't implement a method, the runtime follows a forwarding chain:

1. forwardingTargetForSelector: — redirect to another object

2. methodSignatureForSelector: — construct a method signature

3. forwardInvocation: — handle the invocation manually

4. If none handled — "unrecognized selector" exception

References