1/*********************************************************************** 2 * realizeClassWithoutSwift 3 * Performs first-time initialization on class cls, 4 * including allocating its read-write data. 5 * Does not perform any Swift-side initialization. 6 * Returns the real class structure for the class. 7 * Locking: runtimeLock must be write-locked by the caller 8 **********************************************************************/ 9 static Class realizeClassWithoutSwift(Class cls, Class previously) 10 { 11 runtimeLock.assertLocked(); 13 class_rw_t *rw; 14 Class supercls; 15 Class metacls; 17if (!cls) return nil; 18if (cls->isRealized()) return cls; 19 ASSERT(cls == remapClass(cls)); 21// fixme verify class is not in an un-dlopened part of the shared cache? 23auto ro = (const class_ro_t *)cls->data(); 24 auto isMeta = ro->flags & RO_META;// 元类判断 25if (ro->flags & RO_FUTURE) { 26// This was a future class. rw data is already allocated. 27rw = cls->data(); 28ro = cls->data()->ro(); 29 ASSERT(!isMeta); 30cls->changeInfo(RW_REALIZED|RW_REALIZING, RW_FUTURE); 31 } else { 32// Normal class. Allocate writeable class data. 33 rw = objc::zalloc<class_rw_t>();// 开辟空间 34rw->set_ro(ro);// ro 数据赋值给 rw 35rw->flags = RW_REALIZED|RW_REALIZING|isMeta; 36cls->setData(rw);// cls 重新将 rw 作为其 data 赋值 37 } 39 #if FAST_CACHE_META 40if (isMeta) cls->cache.setBit(FAST_CACHE_META); 41 #endif 43// Choose an index for this class. 44// Sets cls->instancesRequireRawIsa if indexes no more indexes are available 45cls->chooseClassArrayIndex(); 47if (PrintConnecting) { 48 _objc_inform("CLASS: realizing class '%s'%s %p %p #%u %s%s", 49cls->nameForLogging(), isMeta ? " (meta)" : "", 50 (void*)cls, ro, cls->classArrayIndex(), 51cls->isSwiftStable() ? "(swift)" : "", 52cls->isSwiftLegacy() ? "(pre-stable swift)" : ""); 53 } 55// Realize superclass and metaclass, if they aren't already. 56// This needs to be done after RW_REALIZED is set above, for root classes. 57// This needs to be done after class index is chosen, for root metaclasses. 58// This assumes that none of those classes have Swift contents, 59// or that Swift's initializers have already been called. 60// fixme that assumption will be wrong if we add support 61// for ObjC subclasses of Swift classes.// cls 的所有的父类 元类 全部实现、确定 --> 继承链确定下来 62supercls = realizeClassWithoutSwift(remapClass(cls->superclass), nil);// 父类 递归 63metacls = realizeClassWithoutSwift(remapClass(cls->ISA()), nil);// 元类 递归 65 #if SUPPORT_NONPOINTER_ISA // isa 的设置 66if (isMeta) { 67// Metaclasses do not need any features from non pointer ISA 68// This allows for a faspath for classes in objc_retain/objc_release. 69cls->setInstancesRequireRawIsa(); 70 } else { 71// Disable non-pointer isa for some classes and/or platforms. 72// Set instancesRequireRawIsa. 73bool instancesRequireRawIsa = cls->instancesRequireRawIsa(); 74 bool rawIsaIsInherited = false; 75 static bool hackedDispatch = false; 77if (DisableNonpointerIsa) { 78// Non-pointer isa disabled by environment or app SDK version 79 instancesRequireRawIsa = true; 80 } 81elseif (!hackedDispatch && 0 == strcmp(ro->name, "OS_object")) 82 { 83// hack for libdispatch et al - isa also acts as vtable pointer 84 hackedDispatch = true; 85 instancesRequireRawIsa = true; 86 } 87elseif (supercls && supercls->superclass && 88supercls->instancesRequireRawIsa()) 89 { 90// This is also propagated by addSubclass() 91// but nonpointer isa setup needs it earlier. 92// Special case: instancesRequireRawIsa does not propagate 93// from root class to root metaclass 94 instancesRequireRawIsa = true; 95 rawIsaIsInherited = true; 96 } 98if (instancesRequireRawIsa) { 99cls->setInstancesRequireRawIsaRecursively(rawIsaIsInherited); 100 } 101 } 102// SUPPORT_NONPOINTER_ISA 103 #endif 104// 更新父类和元类 105// Update superclass and metaclass in case of remapping 106cls->superclass = supercls; 107cls->initClassIsa(metacls); 109// Reconcile instance variable offsets / layout. 110// This may reallocate class_ro_t, updating our ro variable. 111if (supercls && !isMeta) reconcileInstanceVariables(cls, supercls, ro); 113// Set fastInstanceSize if it wasn't set already. 114cls->setInstanceSize(ro->instanceSize); 116// Copy some flags from ro to rw 117if (ro->flags & RO_HAS_CXX_STRUCTORS) { 118cls->setHasCxxDtor(); 119if (! (ro->flags & RO_HAS_CXX_DTOR_ONLY)) { 120cls->setHasCxxCtor(); 121 } 122 } 124// Propagate the associated objects forbidden flag from ro or from 125// the superclass. 126if ((ro->flags & RO_FORBIDS_ASSOCIATED_OBJECTS) || 127 (supercls && supercls->forbidsAssociatedObjects())) 128 { 129rw->flags |= RW_FORBIDS_ASSOCIATED_OBJECTS; 130 } 132// Connect this class to its superclass's subclass lists 133if (supercls) { 134 addSubclass(supercls, cls); 135 } else { 136 addRootClass(cls); 137 } 139// Attach categories 140 methodizeClass(cls, previously); 142 return cls; 143 }
1staticvoid 2 prepareMethodLists(Classcls, method_list_t **addedLists, intaddedCount, 3 boolbaseMethods, boolmethodsFromBundle) 4 { 5 runtimeLock.assertLocked(); 7if (addedCount == 0) return; 9// There exist RR/AWZ/Core special cases for some class's base methods. 10// But this code should never need to scan base methods for RR/AWZ/Core: 11// default RR/AWZ/Core cannot be set before setInitialized(). 12// Therefore we need not handle any special cases here. 13if (baseMethods) { 14 ASSERT(cls->hasCustomAWZ() && cls->hasCustomRR() && cls->hasCustomCore()); 15 } 17// Add method lists to array. 18// Reallocate un-fixed method lists. 19// The new methods are PREPENDED to the method list array. 21for (int i = 0; i < addedCount; i++) { 22 method_list_t *mlist = addedLists[i]; 23 ASSERT(mlist); 25// Fixup selectors if necessary 26if (!mlist->isFixedUp()) { 27// 方法排序 28 fixupMethodList(mlist, methodsFromBundle, true/*sort*/); 29 } 30 } 32// If the class is initialized, then scan for method implementations 33// tracked by the class's flags. If it's not initialized yet, 34// then objc_class::setInitialized() will take care of it. 35if (cls->isInitialized()) { 36 objc::AWZScanner::scanAddedMethodLists(cls, addedLists, addedCount); 37 objc::RRScanner::scanAddedMethodLists(cls, addedLists, addedCount); 38 objc::CoreScanner::scanAddedMethodLists(cls, addedLists, addedCount); 39 } 40 }