我们可以从https://opensource.apple.com/tarballs/objc4/下载到最新的runtime源码。
目前,最新的是objc4-706.tar.gz压缩包。
打开工程后,目录是这样的:

1
2
3
4
5
6
7
8
objc--
--Public Headers
--Private Headers
--Project Headers
--Obsolete Headers
--Obsolete Source
--Souce
--Other
1
2
3
4
5
6
/// A pointer to the function of a method implementation.
#if !OBJC_OLD_DISPATCH_PROTOTYPES
typedef void (*IMP)(void /* id, SEL, ... */ );
#else
typedef id (*IMP)(id, SEL, ...);
#endif

IMP是指向方法实现的指针。
一些 runtime 常用的方法:
1.返回 SEL 的方法名
const char sel_getName(SEL sel) / SELNAME(sel)
2.根据 SEL 注册方法
SEL sel_registerName(const char
str) / NAMEOF(obj)
3.根据 obj 对象获取 obj 的 className
const char *object_getClassName(id obj)

typedef struct objc_class Class;
struct objc_object {
Class isa;
}
typedef struct objc_object
id;
typedef struct objc_selector *SEL;

Public Headers/objc.h 中objc_object结构体是这样的:

1
2
3
struct objc_object {
Class isa;
}

Project Headers/objc-private.h 中的 objc_object结构体:
// 对象的结构体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
struct objc_object {
private:
isa_t isa;
public:
Class ISA();
Class getIsa();
void initIsa(Class cls);
void initClassIsa(Class cls);
void initProtocolIsa(Class cls);
void initInstanceIsa(Class cls, bool hasCxxDtor);
Class changeIsa(Class newCls);
bool hasNonpointerIsa();
bool isTaggedPointer();
bool isBasicTaggedPointer();
bool isExtTaggedPointer();
bool isClass();
bool hasAssociatedOjects();
void setHasAssociatedObjects();
bool isWeaklyReferenced();
void setWeaklyReferenced_nolock();
// have -.cxx_destruct
bool hasCxxDtor();
id retain();
void release();
id autorelease();
id rootRetain();
bool rootRelease();
id rootAutorelease();
bool rootTryRetain();
bool rootReleaseShouldDealloc();
uintptr_t rootRetainCount();
bool rootIsDeallocating();
void clearDeallocating();
void rootDealloc();
Private:
void initIsa(Class newCls, bool nonpointer, bool hasCxxDtor);
id rootAutorelease2();
bool overrelease_error();
#if Support_nonpointer_isa
...
#endif
...
};
1
2
3
4
5
6
7
8
9
10
11
#if __OBJC2__
typedef struct method_t *Method;
typedef struct ivar_t *Ivar;
typedef struct category_t *Category;
typedef struct property_t *objc_property_t;
#else
typedef struct old_method *Method;
typedef struct old_ivar *Ivar;
typedef struct old_category *Category;
typedef struct old_property *objc_property_t;
#endif

在 OC 2.0以后,有很多变化,
Project Headers/objc-runtime-new.h中,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
struct method_t {
SEL name;
const char types;
IMP imp;
struct SortBySELAddress :
public std::binary_function<const method_t&,const method_t&,bool> {
bool operator() (const method_t lhs, const method_t& rhs) {
return lhs.name < rhs.name;
}
}
}
struct ivar_t {
int32_t *offset;
const char *name;
const char *type;
uint32_t alignment_raw;
uint32_t size;
uint32_t alignment() const {
if (alignment_raw == ~(uint32_t)0)
return 1U << WORD_SHIFT;
return 1 << alignment_raw;
}
}
struct category_t {
const char *name;
classref_t cls;
struct method_list_t *instanceMethod;
struct method_list_t *classMethods;
struct protocol_list_t *protocols;
struct property_list_t *instanceProperties;
struct property_list_t *_classProperties;
method_list_t *methodsForMeta(bool isMeta) {
if(isMeta)
return classMethods;
else
return instanceMethods;
}
property_list_t *propertiesForMeta(bool isMeta, struct header_info *hi);
}
struct property_t {
const char *name;
const char *attributes;
}
// Class 的定义
struct objc_class : objc_object {
Class superclass;
cache_t cache;
class_data_bits_t bits;
class_rw_t *data() {
return bits.data();
}
void setData(class_rw_t *newData) {
bits.setData(newData);
}
void setInfo(uint32_t set) {
assert(isFuture() || isRealized());
data()->setFlags(set);
}
void clearInfo(uint32_t clear) {
assert(isFuture() || isRealized());
data()->clearFlags(clear);
}
void changeInfo(uint32_t set, uint32_t clear) {
assert(isFuture() || isRealized());
assert((set & clear) == 0);
data()->changeFlags(set, clear);
}
bool hasCustomRR() {
return !bits.hasDefaultRR();
}
void setHasDefaultRR() {
assert(isInitializing());
bits.setHasDefaultRR();
}
void setHasCustomRR(bool inherited = false);
void printCustomRR(bool inherited);
bool hasCustomAWZ() {
return !bits.hasDefaultAWZ();
}
void setHasCustomAWZ(bool inherited = false);
void printCustomAWZ(bool inherited);
bool instancesRequireRawIsa() {
return bits.instancesRequireRawIsa();
}
void setInstanceRequireRawIsa(bool iinherited);
void printInstanceRequireRawIsa(bool inherited);
bool canAllocNonpointer() {
assert(!isFuture());
return !instancesRequireRawIsa();
}
bool canAllocFast() {
assert(!isFuture());
return bits.canAllocFast();
}
bool hasCxxCtor() {
assert(!isRealized());
return bits.hasCxxCtor();
}
void setHasCxxCtor() {
bits.setHasCxxCtor();
}
bool hasCxxDtor() {
assert(isRealized());
return bits.hasCxxDtor();
}
void setHasCxxDtor() {
bits.setHasCxxDtor();
}
bool isSwift() {
return bits.isSwift();
}
bool hasAutomaticIvars() {
return data()->ro->flags & (RO_IS_ARC | RO_HAS_WEAK_WITHOUT_ARC);
}
bool isARC() {
return data()->ro->flags & RO_IS_ARC;
}
bool instancesHaveAssociatedObjects() {
assert(isFuture() || isRealized());
return data()->flags & RW_INSTANCES_HAVE_ASSOCIATED_OBJECTS;
}
void setInstancesHaveAssociatedObjects() {
assert(isFuture() || isRealized());
setInfo(RW_INSTANCES_HAVE_ASSOCIATED_OBJECTS);
}
bool shouldGrowCache() {
return true;
}
void setShouldGrowCache(bool) {
//fixme good or bad for memory use?
}
bool isInitializing() {
return getMeta->data()->flags & RW_INITIALIZING;
}
void setInitializing() {
assert(!isMetaClass());
ISA()->setInfo(RW_INITIALIZING);
}
bool isInitialized() {
return getMeta()->data()->falgs & RW_INITIALIZED;
}
void setInitialized();
bool isLoadable() {
assert(isRealized());
return true;
}
IMP getLoadMethod();
bool isRealized() {
return data()->falgs & RW_REALIZED;
}
bool isFuture() {
return data()->flags & RW_TUTURE;
}
bool isMetaClass() {
assert(this);
assert(isRealized());
return data()->ro->flags & RO_META;
}
Class getMeta() {
if(isMetaClass())
return (Class)this;
else
return this->ISA();
}
bool isRootClass() {
return superclass == nil;
}
bool isRootMetaClass() {
return ISA() == (Class)this;
}
const char *mangledName() {
assert(this);
if(isRealized() || isFuture()) {
return data()->ro->name;
} else {
return ((const class_ro-t *)data())->name;
}
}
const char *demangledName(bool realize = false);
const char *nameForLogging();
uint32_t unalignedInstanceStart() {
assert(isRealized());
return data()->ro->instanceStart;
}
uint32_t alignedInstanceStart() {
return word_align(unalignedInstanceStart());
}
uint32_t unalignedInstanceSize() {
assert(isRealized());
return data()->ro->instanceSize;
}
size_t instanceSize(size_t extraBytes) {
size_t size = alignedInstanceSize() + extraBytes;
if(size < 16)
size = 16;
return size;
}
void setInstanceSize(uint32_t newSize) {
assert(isRealized());
if(newSize != data()->ro->instanceSize) {
assert(data()->flags & RW_COPIED_RO);
*const_cast<uint32_t *>(&data()->ro->instanceSize) = newSize;
}
bits.setFastInstanceSize(newSize);
}
void setClassArrayIndex(unsigned Idx) {
bits.setClassArrayIndex(Idx);
}
unsigned classArrayIndex() {
return bits.classArrayIndex();
}
}
struct objc_super2 {
id receiver;
Class current_class;
}

Public Headers/runtime.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
struct objc_method_description {
SEL name;
char *types; //methods arguments types
}
typedef struct {
const char *name;
const char *value; //usually empty
} objc_property_attribute_t;
/* Working with Instances */
id object_copy(id obj, size_t size);
id object_dispose(id obj);
Class object_getClass(id obj);
Class object_setClass(id obj, Class cls);
BOOL object_isClass(id obj);
const char *object_getClassName(id obj);
id object_getIvar(id obj, Ivar ivar)
// set instance var value:(Instance variables with unknown memory management are assigned as if they were unsafe_unretained.)
void object_setIvar(id obj, Ivar ivar, id value);
// (Instance variables with unknown memory management are assigned as if they were strong)
void object_setIvarWithStrongDefault(id obj, Ivar ivar, id value);
/* Obtaining Class Definitions */
Class objc_getClass(const char *name);
Class objc_getMetaClass(const char *name);
Class objc_lookUpClass(const char *name);
Class objc_getRequiredClass(const char *name);
int objc_getClassList(Class *buffer, int bufferCount);
Class *objc_copyClassList(unsigned int *outCount);
/* Working with Classes */
const char *class_getName(Class cls);
Bool class_isMetaClass(Class cls);
int class_getVersion(Class cls);
void class_setVersion(Class cls, int version);
size_t class_getInstanceSize(Class cls);
Ivar class_getInstanceVariable(Class cls, const char *name);
Ivar class_getClassVariable(Class cls, const char *name);
Ivar *class_copyIvarList(Class cls, unsigned int *outCount);
Method class_getInstanceMethod(Class cls, SEL name);
Method class_getClassMethod(Class cls, SEL name);
IMP class_getMethodImplementation(Class cls, SEL name);
BOOL class_respondsToSelector(Class cls, SEL sel);
Method *class_copyMethodList(Class cls, unsigned int *outCount);
BOOL class_conformsToProtool(Class cls, Protocol *protocol);
Protocol * __unsafe_unretained *class_copyProtocolList(Class cls, unsigned int *outCount);
objc_property_t class_getProperty(Class cls, const char *name);
objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount);
const uint8_t *class_getIvarLayout(Class cls);
const uint8_t *class_getWeakIvarLayout(Class cls);
BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *name);
IMP class_replaceMethod(Class cls, SEL name, IMP imp, const char *types);
BOOL class_addIvar(Class cls, const char *name, sizet_t size, uint8_t alignment, const char *types);
BOOL class_addProtocol(Class cls ,Protocol *protocol);
BOOL class_addProperty(Class cls, const char *name, const objc_propety_attrbute_t *attributes, unsigned int attributeCount);
void class_repalceProperty(Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount);
void class_setIvarLayout(Class cls, const uint8_t *layout);
void class_setWeakIvarLayout(Class cls, const uint8_t *layout);
/* Adding Classes */
Class objc_allocateClassPair(Class superclass, const char *name, size_t sxtraBytes);
void objc_registerClassPair(Class cls);
Class objc_duplicateClass(Class original, const char *name, size_t extraBypes);
void objc_disposeClassPair(Class cls);
/* Working with Methods */
SEL method_getName(Method m);
IMP method_getImplementation(Method m);
const char *method_getTypeEncoding(Method m);
unsigned int method_getNumberOfArguments(Method m);
char *method_copyReturnType(Method m);
char *method_copyArgumentType(Method m, unsigned int index);
void method_getReturnType(Method m, char *dst, size_t dst_len);
void method_getArgumentType(Method m, unsigned int index, char *dst, size_t dst_len);
struct objc_method_description *method_getDescription(Method m);
IMP method_setImplementation(Method m, IMP imp);
void method_exchangeImplementations(Method m1, Method m2);
/* Working with Instance Variables */
const char *ivar_getName(Ivar v);
const char *ivar_getTypeEncoding(Ivar v);
ptrdiff_t ivar_getOffset(Ivar v);
/* Working with Properties */
const char *property_getName(objc_property_t property);
const char *property_getAttributes(objc_property_t property);
objc_property_attribute_t *property_copyAttributeList(objc_property_t property, unsigned int *outCount);
char *property_copyAttributeValue(objc_property_t property, const char *attributeName);
/* Working with Protocols */
Protocol *objc_getProtocol(const char *name);
Protocol * __unsafe_unretained *objc_copyProtocolList(unsigned int *outCount);
BOOL protocol_conformsToProtocol(Protocol *proto, Protocol *other);
BOOL protocol_isEqual(Protocol *proto, Protocol *other);
const char *protocol_getName(Protocol *p);
struct objc_method_description protocol_getMethodDescription(Protocol *p, SEL aSel, BOOL isRequiredMethod, BOOL isInstanceMethod);
struct objc_method_description *protocol_copyMethodDescriptionList(Protocol *p, BOOL isRequiredMethod, BOOL inInstanceMethod, unsigned int *outCount);
objc_property_t protocol_getProperty(Protocol *proto, const char *name, BOOL isRequiredProperty, BOOL isInstanceProperty);
objc_property_t *protocol_copyPropertyList(Protocol *proto, unsigned int *outCount);
objc_property_t *protocol_copyPropertyList2(Protocol *proto, unsigned int *outCount, BOOL isRequiredProperty, BOOL isInstanceProperty);
Protocol * __unsafe_unretained *protocol_copyProtocolList(Protocol *proto, unsigned int *outCount);
Protocol *objc_allocateProtocol(const char *name);
void objc_registerProtocol(Protocol *proto);
void protocol_addMethodDescription(Protocol *proto, SEL name, const char *types, BOOL isRequiredMethod, BOOL isInstanceMethod);
void protocol_addProtocol(Protocol *proto, Protocol *addition);
void protocol_addProperty(Protocol *proto, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount, BOOL isRequiredProperty, BOOL isInstanceProperty);
/* Working with Libraries */
const char **objc_copyImageNames(unsigned int *outCount);
const char *class_getImageName(Class cls);
const char **objc_copyClassNameForImage(const char *image, unsigned int *outCount);
/* Working with Selectors */
const char *sel_getName(SEL sel);
SEL sel_getUid(const char *str);
SEL sel_registerName(const char *str);
BOOL sel_isEqual(SEL lhs, SEL rhs);
/* OC Language Features */
void objc_enumerationMutation(id obj);
void objc_setEnumerationMutationHandler(void (*handler)(id));
void objc_setForwardHandler(void *fwd, void *fwd_stret);
IMP imp_implementationWithBlock(id block);
id imp_getBlock(IMP anImp);
BOOL imp_removeBlock(IMP anImp);
id objc_loadWeak(id *location);
id objc_storeWeak(id *location, id obj);
/* Associative references */
void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);
id objc_getAssociatedObject(id object, const void *key);
void objc_removeAssociatedObjects(id object);