SlideShare a Scribd company logo
The Objective-c Runtime
Павел Альбицкий
p.albitsky@gmail.com
Open source
libobjc.dylib
http://www.opensource.apple.com/source/objc
4/objc4-680/
Functions
class_getName
class_getSuperclass
class_setSuperclass
class_isMetaClass
class_getInstanceSize
class_getInstanceVariable
class_getClassVariable
class_addIvar
class_copyIvarList
class_getIvarLayout
class_setIvarLayout
class_getWeakIvarLayout
class_setWeakIvarLayout
class_getProperty
class_copyPropertyList
class_addMethod
class_getInstanceMethod
class_getClassMethod
class_copyMethodList
class_replaceMethod
class_getMethodImplementation
class_getMethodImplementation_stret
class_respondsToSelector
class_addProtocol
class_addProperty
class_replaceProperty
class_conformsToProtocol
class_copyProtocolList
class_getVersion
class_setVersion
objc_getFutureClass
objc_setFutureClass
Working with Classes
Adding Classes
objc_allocateClassPair
objc_disposeClassPair
objc_registerClassPair
objc_duplicateClass
Instantiating Classes
class_createInstance
objc_constructInstance
objc_destructInstance
Working with Instances
object_copy
object_dispose
object_setInstanceVariable
object_getInstanceVariable
object_getIndexedIvars
object_getIvar
object_setIvar
object_getClassName
object_getClass
object_setClass
Obtaining Class Definitions
objc_getClassList
objc_copyClassList
objc_lookUpClass
objc_getClass
objc_getRequiredClass
objc_getMetaClass
Working with Instance Variables
ivar_getName
ivar_getTypeEncoding
ivar_getOffset
Associative References
objc_setAssociatedObject
objc_getAssociatedObject
objc_removeAssociatedObjects
NSObject.mm
+ (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = object_getClass((id)self); tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
- (BOOL)respondsToSelector:(SEL)sel {
if (!sel) return NO;
return class_respondsToSelector_inst([self class], sel, self);
}
- (BOOL)conformsToProtocol:(Protocol *)protocol {
if (!protocol) return NO;
for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
if (class_conformsToProtocol(tcls, protocol)) return YES;
}
return NO;
}
- (id)performSelector:(SEL)sel {
if (!sel) [self doesNotRecognizeSelector:sel];
return ((id(*)(id, SEL))objc_msgSend)(self, sel);
}
NSObject
@interface NSObject <NSObject> {
Class isa;
}
typedef struct objc_class *Class;
struct objc_class {
Class isa;
#if !__OBJC2__
Class super_class
const char *name
long version
long info
long instance_size
struct objc_ivar_list *ivars
struct objc_method_list **methodLists
struct objc_cache *cache
struct objc_protocol_list *protocols
#endif
};
NSObject
typedef struct objc_object *id;
typedef struct objc_selector *SEL;
typedef struct objc_method *Method;
typedef struct objc_ivar *Ivar;
typedef struct objc_category *Category;
typedef struct objc_property *objc_property_t;
typedef struct objc_object Protocol;
Class hierarchy
@interface BaseExample : NSObject {
NSString *_ivarBase;
}
@property(nonatomic, strong) NSString *baseProperty;
- (void)test;
+ (NSString *)baseClassMethod;
@end
#import "BaseExample.h"
@interface Example : BaseExample {
NSString *_ivarExample;
}
@property(nonatomic, strong) NSString *exampleProperty;
- (void)test;
- (NSString *)execWithParam:(NSString *)param;
+ (NSString *)exampleClassMethod;
@end
Instance of Example Class Example Metaclass Example
isa isa
Class BaseExample
isa
Class NSObject
isa
Metaclass
BaseExample
Metaclass NSObject
super_class
super_class
super_class
super_class
Class hierarchy
struct objc_method {
SEL method_name; // signature of method
char *method_types; // types of the parameters to the method
IMP method_imp; // memory address of the start of code block
};
typedef struct objc_method *Method;
A selector is the name used to select a method to execute for an object, or the
unique identifier that replaces the name when the source code is compiled.
Selector – C-string;
IMP - typedef id (*IMP)(id self,SEL _cmd,...);
Method
NSString *result = [example execWithParam:@"param"];
id objc_msgSend(id self, SEL op, ...)
result = objc_msgSend(example, @selector(execWithParam:), @"param");
Tail-call: typedef id (*IMP)(id self,SEL _cmd,...);
void objc_msgSend(void /* id self, SEL op, ... */ )
NSString *result = ((NSString* (*)(id, SEL, NSString *))objc_msgSend)(example,
@selector(execWithParam:), @"param");
Sending Messages
id objc_msgSend(id self, SEL op, ...)
Sends a message with a simple return value to an instance of a class.
double objc_msgSend_fpret(id self, SEL op, ...)
Sends a message with a floating-point return value to an instance of a class.
void objc_msgSend_stret(void * stretAddr, id theReceiver, SEL theSelector, ...)
Sends a message with a data-structure return value to an instance of a class.
id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
Sends a message with a simple return value to the superclass of an instance of a class.
void objc_msgSendSuper_stret(struct objc_super *super, SEL op, ...) Sends a message with a
data-structure return value to the superclass of an instance of a class.
objc_msgSend
Message forwarding
resolveInstanceMethod
forwardingTargetForSelector
forwardInvocation
Message handled
Message
not handled
Return NO
Return YES
Return nil
Return
replacement
receiver
resolveInstanceMethod
1. Class cache -> class dispatch table -> all super classes
2. resolveInstanceMethod for @dynamic properties
id dynamicGetter(id self, SEL _cmd);
void dynamicSetter(id self, SEL _cmd, id value);
+ (BOOL)isDynamicProperty:(NSString *)selectorString;
+ (BOOL)resolveInstanceMethod:(SEL)sel {
NSString *selectorString = NSStringFromSelector(sel);
if ([self isDynamicProperty:selectorString]) {
if ([selectorString hasPrefix:@"set"]) {
class_addMethod(self, sel, (IMP)dynamicSetter, "v@:@");
} else {
class_addMethod(sel, sel, (IMP)dynamicGetter, "@@:");
}
return YES;
}
return [super resolveInstanceMethod:sel];
}
// "v@:@", "@@:" - Objective-C type encodings
forwardingTargetForSelector
3. The Runtime then calls forwardingTargetForSelector
Returns the object to which unrecognized messages should first be directed.
- (id)forwardingTargetForSelector:(SEL)aSelector {
if (aSelector == @selector(magicMethod:)) {
return magicObject;
} else {
return [super forwardingTargetForSelector:aSelector];
}
}
forwardInvocation
@implementation InvClass
- (NSString *)invWithFirst:(NSString *)first second:(NSNumber *)second
third:(NSArray *)third {
return [NSString stringWithFormat:@"first: %@, second: %@, third: %@", first, second,
third];
}
@end
// perform unrecognized selector
Example *example = [Example new];
SEL selector = @selector(invWithFirst:);
NSString *result = [example performSelector:selector
withObject:@"first"];
forwardInvocation
+ (BOOL)resolveInstanceMethod:(SEL)sel {
if (sel == @selector(invWithFirst:)) {
return NO;
}
return YES;
}
- (id)forwardingTargetForSelector:(SEL)aSelector {
if (aSelector == @selector(invWithFirst:)) {
return nil;
}
return [super forwardingTargetForSelector:aSelector];
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
NSMethodSignature* signature = [super methodSignatureForSelector:aSelector];
if (!signature) {
SEL customSelector = @selector(invWithFirst:second:third:);
signature = [_invObject methodSignatureForSelector:customSelector];
}
return signature;
}
forwardInvocation
- (void)forwardInvocation:(NSInvocation *)anInvocation {
SEL selector = anInvocation.selector;
if ([_invObject respondsToSelector:selector]) {
[anInvocation setTarget:_invObject];
SEL customSelector = @selector(invWithFirst:second:third:);
[anInvocation setSelector:customSelector];
NSString *first = @"first";
NSNumber *second = @2;
NSArray *third = @[@”3", @”33”, @”333"];
[anInvocation setArgument:&first atIndex:2];
[anInvocation setArgument:&second atIndex:3];
[anInvocation setArgument:&third atIndex:4];
[anInvocation invoke];
} else {
[self doesNotRecognizeSelector:selector];
}
}
Method Swizzling
#import <objc/runtime.h>
@import Crashlytics;
@implementation UIViewController (Tracking)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
SEL originalSelector = @selector(viewWillAppear:);
SEL swizzledSelector = @selector(swizzled_viewWillAppear:);
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
BOOL didAddMethod =
class_addMethod(class,
originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(class,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
});
}
- (void)swizzled_viewWillAppear:(BOOL)animated {
CLS_LOG(@"CLSLOG viewWillAppear: %@", self);
[self swizzled_viewWillAppear:animated];
}
@end
URLs
• Mike Ash
• Objective-C Runtime Reference
• Objective-C Runtime Programming Guide
• opensource.apple.com
Спасибо за внимание!
Павел Альбицкий
p.albitsky@gmail.com

More Related Content

What's hot (20)

DOC
Ad java prac sol set
Iram Ramrajkar
 
PPTX
Javascript Basics
msemenistyi
 
PDF
Introduction to Clean Code
Julio Martinez
 
PPTX
Intro to Javascript
Anjan Banda
 
PPT
eXo SEA - JavaScript Introduction Training
Hoat Le
 
PDF
Advanced Java Practical File
Soumya Behera
 
PDF
Fundamental JavaScript [UTC, March 2014]
Aaron Gustafson
 
PPT
Test driven development_for_php
Lean Teams Consultancy
 
PPT
JavaScript Tutorial
Bui Kiet
 
PDF
Java Script Best Practices
Enrique Juan de Dios
 
PDF
Important java programs(collection+file)
Alok Kumar
 
PPT
Java tutorial for Beginners and Entry Level
Ramrao Desai
 
PPT
JavaScript Objects
Reem Alattas
 
PDF
Pavel kravchenko obj c runtime
DneprCiklumEvents
 
PPTX
Building l10n Payroll Structures from the Ground up
Odoo
 
PPT
Javascript
mussawir20
 
KEY
Parte II Objective C
Paolo Quadrani
 
PDF
Variables, expressions, standard types
Rubizza
 
PDF
Java script introducation & basics
H K
 
PDF
Declarative Data Modeling in Python
Joshua Forman
 
Ad java prac sol set
Iram Ramrajkar
 
Javascript Basics
msemenistyi
 
Introduction to Clean Code
Julio Martinez
 
Intro to Javascript
Anjan Banda
 
eXo SEA - JavaScript Introduction Training
Hoat Le
 
Advanced Java Practical File
Soumya Behera
 
Fundamental JavaScript [UTC, March 2014]
Aaron Gustafson
 
Test driven development_for_php
Lean Teams Consultancy
 
JavaScript Tutorial
Bui Kiet
 
Java Script Best Practices
Enrique Juan de Dios
 
Important java programs(collection+file)
Alok Kumar
 
Java tutorial for Beginners and Entry Level
Ramrao Desai
 
JavaScript Objects
Reem Alattas
 
Pavel kravchenko obj c runtime
DneprCiklumEvents
 
Building l10n Payroll Structures from the Ground up
Odoo
 
Javascript
mussawir20
 
Parte II Objective C
Paolo Quadrani
 
Variables, expressions, standard types
Rubizza
 
Java script introducation & basics
H K
 
Declarative Data Modeling in Python
Joshua Forman
 

Similar to Objective-c Runtime (20)

PDF
«Objective-C Runtime в примерах» — Алексей Сторожев, e-Legion
e-Legion
 
PDF
Objective c runtime
Inferis
 
PDF
self and super in objc
Vonbo
 
PDF
The Dark Side of Objective-C
Martin Kiss
 
PDF
What Makes Objective C Dynamic?
Kyle Oba
 
PPT
iOS Application Development
Compare Infobase Limited
 
KEY
Runtime
Jorge Ortiz
 
PPTX
Presentation 1st
Connex
 
PPT
Objective c intro (1)
David Echeverria
 
PPT
Cocoa for Web Developers
georgebrock
 
KEY
連邦の白いヤツ 「Objective-C」
matuura_core
 
PPTX
Presentation 3rd
Connex
 
PDF
201005 accelerometer and core Location
Javier Gonzalez-Sanchez
 
PPTX
From C++ to Objective-C
corehard_by
 
PDF
Objective-C Runtime overview
Fantageek
 
PDF
Никита Корчагин - Programming Apple iOS with Objective-C
DataArt
 
PPTX
Objective-c for Java Developers
Muhammad Abdullah
 
PDF
Introduction to objective c
Sunny Shaikh
 
PDF
iOS Programming Intro
Lou Loizides
 
KEY
RubyistのためのObjective-C入門
S Akai
 
«Objective-C Runtime в примерах» — Алексей Сторожев, e-Legion
e-Legion
 
Objective c runtime
Inferis
 
self and super in objc
Vonbo
 
The Dark Side of Objective-C
Martin Kiss
 
What Makes Objective C Dynamic?
Kyle Oba
 
iOS Application Development
Compare Infobase Limited
 
Runtime
Jorge Ortiz
 
Presentation 1st
Connex
 
Objective c intro (1)
David Echeverria
 
Cocoa for Web Developers
georgebrock
 
連邦の白いヤツ 「Objective-C」
matuura_core
 
Presentation 3rd
Connex
 
201005 accelerometer and core Location
Javier Gonzalez-Sanchez
 
From C++ to Objective-C
corehard_by
 
Objective-C Runtime overview
Fantageek
 
Никита Корчагин - Programming Apple iOS with Objective-C
DataArt
 
Objective-c for Java Developers
Muhammad Abdullah
 
Introduction to objective c
Sunny Shaikh
 
iOS Programming Intro
Lou Loizides
 
RubyistのためのObjective-C入門
S Akai
 
Ad

Objective-c Runtime