1
- #include "magic_objects.h"
2
1
#include "objc/runtime.h"
3
2
#include "objc/hooks.h"
4
3
#include "objc/developer.h"
@@ -161,21 +160,6 @@ BOOL objc_resolve_class(Class cls)
161
160
}
162
161
163
162
164
- // Give up if we can't resolve the root class yet...
165
- static Class root_class = Nil ;
166
- if (Nil == root_class )
167
- {
168
- root_class = (Class )objc_getClass (ROOT_OBJECT_CLASS_NAME );
169
- if (Nil == root_class ) { return NO ; }
170
-
171
- if (cls != root_class && !objc_test_class_flag (root_class , objc_class_flag_resolved ))
172
- {
173
- objc_resolve_class (root_class );
174
- }
175
- assert (root_class );
176
- }
177
-
178
-
179
163
// Remove the class from the unresolved class list
180
164
if (Nil == cls -> unresolved_class_prev )
181
165
{
@@ -194,45 +178,60 @@ BOOL objc_resolve_class(Class cls)
194
178
cls -> unresolved_class_prev = Nil ;
195
179
cls -> unresolved_class_next = Nil ;
196
180
197
- // Resolve the superclass pointer
181
+ // The superclass for the metaclass. This is the metaclass for the
182
+ // superclass if one exists, otherwise it is the root class itself
183
+ Class superMeta = Nil ;
184
+ // The metaclass for the metaclass. This is always the root class's
185
+ // metaclass.
186
+ Class metaMeta = Nil ;
198
187
199
- // If this class has no superclass, use [NS]Object
200
- Class super = root_class ;
201
- Class superMeta = root_class ;
202
- Class meta = cls -> isa ;
188
+ // Resolve the superclass pointer
203
189
204
- if (NULL != cls -> super_class )
190
+ if (NULL == cls -> super_class )
191
+ {
192
+ superMeta = cls ;
193
+ metaMeta = cls -> isa ;
194
+ }
195
+ else
205
196
{
206
197
// Resolve the superclass if it isn't already resolved
207
- super = (Class )objc_getClass ((char * )cls -> super_class );
198
+ Class super = (Class )objc_getClass ((char * )cls -> super_class );
208
199
if (!objc_test_class_flag (super , objc_class_flag_resolved ))
209
200
{
210
201
objc_resolve_class (super );
211
202
}
212
203
superMeta = super -> isa ;
213
204
// Set the superclass pointer for the class and the superclass
214
205
cls -> super_class = super ;
206
+ do
207
+ {
208
+ metaMeta = super -> isa ;
209
+ super = super -> super_class ;
210
+ } while (Nil != super );
215
211
}
212
+ Class meta = cls -> isa ;
216
213
217
- // Don't make the root class a subclass of itself
218
- if (cls != super )
214
+ // Make the root class the superclass of the metaclass (e.g. NSObject is
215
+ // the superclass of all metaclasses in classes that inherit from NSObject)
216
+ meta -> super_class = superMeta ;
217
+ meta -> isa = metaMeta ;
218
+
219
+ // Don't register root classes as children of anything
220
+ if (Nil != cls -> super_class )
219
221
{
220
222
// Set up the class links
221
- cls -> sibling_class = super -> subclass_list ;
222
- super -> subclass_list = cls ;
223
+ cls -> sibling_class = cls -> super_class -> subclass_list ;
224
+ cls -> super_class -> subclass_list = cls ;
223
225
}
224
- // Make the root class the superclass of the metaclass (e.g. NSObject is
225
- // the superclass of all metaclasses)
226
- meta -> super_class = superMeta ;
227
226
// Set up the metaclass links
228
227
meta -> sibling_class = superMeta -> subclass_list ;
229
228
superMeta -> subclass_list = meta ;
230
229
231
230
// Mark this class (and its metaclass) as resolved
232
231
objc_set_class_flag (cls , objc_class_flag_resolved );
233
232
objc_set_class_flag (cls -> isa , objc_class_flag_resolved );
234
- cls -> isa -> isa = ( Nil == cls -> isa -> isa ) ? root_class -> isa :
235
- (( Class ) objc_getClass (( char * ) cls -> isa -> isa )) -> isa ;
233
+
234
+
236
235
// Fix up the ivar offsets
237
236
objc_compute_ivar_offsets (cls );
238
237
// Send the +load message, if required
0 commit comments