Class cls; uintptr_t bits; #if defined(ISA_BITFIELD) struct { ISA_BITFIELD; // defined in isa.h }; #endif };
// isa.h ISA_BITFIELD 的定义 #if SUPPORT_PACKED_ISA
// extra_rc must be the MSB-most field (so it matches carry/overflow flags) // nonpointer must be the LSB (fixme or get rid of it) // shiftcls must occupy the same bits that a real class pointer would // bits + RC_ONE is equivalent to extra_rc + 1 // RC_HALF is the high bit of extra_rc (i.e. half of its range)
// future expansion: // uintptr_t fast_rr : 1; // no r/r overrides // uintptr_t lock : 2; // lock for atomic property, @synch // uintptr_t extraBytes : 1; // allocated with extra bytes
// Base class implementation of +alloc. cls is not nil. // Calls [cls alloc]. id objc_alloc(Class cls) { return callAlloc(cls, true/*checkNil*/, false/*allocWithZone*/); }
// Call [cls alloc] or [cls allocWithZone:nil], with appropriate // shortcutting optimizations. static ALWAYS_INLINE id callAlloc(Class cls, bool checkNil, bool allocWithZone=false) { #if __OBJC2__ // 重点关注这一部分,最终都会走到这里 // 检查是否为 nil 对象调用 if (slowpath(checkNil && !cls)) returnnil; // 调用 _objc_rootAllocWithZone if (fastpath(!cls->ISA()->hasCustomAWZ())) { return _objc_rootAllocWithZone(cls, nil); } #endif
NEVER_INLINE id _objc_rootAllocWithZone(Class cls, malloc_zone_t *zone __unused) { // allocWithZone under __OBJC2__ ignores the zone parameter return _class_createInstanceFromZone(cls, 0, nil, OBJECT_CONSTRUCT_CALL_BADALLOC); }
/*********************************************************************** * class_createInstance * fixme * Locking: none * * Note: this function has been carefully written so that the fastpath * takes no branch. **********************************************************************/ static ALWAYS_INLINE id _class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone, int construct_flags = OBJECT_CONSTRUCT_NONE, bool cxxConstruct = true, size_t *outAllocatedSize = nil) { // 是否实现 cls ASSERT(cls->isRealized());
// Read class's info bits all at once for performance // cls 是否有 c++ 的构建方法 bool hasCxxCtor = cxxConstruct && cls->hasCxxCtor(); // cls 是否有 c++ 的析构方法 bool hasCxxDtor = cls->hasCxxDtor(); // cls 是否开启了 isa 优化 bool fast = cls->canAllocNonpointer(); size_t size;
id obj; // zone 是 nil if (zone) { obj = (id)malloc_zone_calloc((malloc_zone_t *)zone, 1, size); } else { // 根据 size 开辟内存 obj = (id)calloc(1, size); } if (slowpath(!obj)) { if (construct_flags & OBJECT_CONSTRUCT_CALL_BADALLOC) { return _objc_callBadAllocHandler(cls); } returnnil; }
if (!zone && fast) { // fast 参数,开启了 isa 优化,初始化 isa_t obj->initInstanceIsa(cls, hasCxxDtor); } else { // Use raw pointer isa on the assumption that they might be // doing something weird with the zone or RR. // 使用为优化的 isa 指针 obj->initIsa(cls); }
void *objc_destructInstance(id obj) { if (obj) { // Read all of the flags at once for performance. bool cxx = obj->hasCxxDtor(); bool assoc = obj->hasAssociatedObjects();
// This order is important. // c++ 析构方法 if (cxx) object_cxxDestruct(obj); // 移除关联对象,并将其自身从Association Manager的map中移除 if (assoc) _object_remove_assocations(obj); // 执行 clearDeallocating obj->clearDeallocating(); }
return obj; }
clearDeallocating
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
inlinevoid objc_object::clearDeallocating() { if (slowpath(!isa.nonpointer)) { // Slow path for raw pointer isa. // 没有使用优化的 isa 指针,清除 SideTable 中的引用计数的数据 sidetable_clearDeallocating(); } elseif (slowpath(isa.weakly_referenced || isa.has_sidetable_rc)) { // Slow path for non-pointer isa with weak refs and/or side table data. // 有弱指针 或者 使用 SideTable 管理引用计数 clearDeallocating_slow(); }
// 如果cache是YES,则从缓存中查找IMP。如果是从cache3函数进来,则不会执行cache_getImp()函数 if (cache) { // 通过cache_getImp函数查找IMP,查找到则返回IMP并结束调用 imp = cache_getImp(cls, sel); if (imp) return imp; }
// runtimeLock is held during isRealized and isInitialized checking // to prevent races against concurrent realization.
// runtimeLock is held during method search to make // method-lookup + cache-fill atomic with respect to method addition. // Otherwise, a category could be added but ignored indefinitely because // the cache was re-filled with the old value after the cache flush on // behalf of the category.
runtimeLock.read();
// 判断类是否已经被创建,如果没有被创建,则将类实例化 (class 的创建时机:第一次接收消息) if (!cls->isRealized()) { // Drop the read-lock and acquire the write-lock. // realizeClass() checks isRealized() again to prevent // a race while the lock is down. runtimeLock.unlockRead(); runtimeLock.write();
// 对类进行实例化操作 realizeClass(cls);
runtimeLock.unlockWrite(); runtimeLock.read(); }
// 第一次调用当前类的话,执行 initialize 的代码 if (initialize && !cls->isInitialized()) { runtimeLock.unlockRead(); // 对类进行初始化,并开辟内存空间 _class_initialize (_class_getNonMetaClass(cls, inst)); runtimeLock.read(); // If sel == initialize, _class_initialize will send +initialize and // then the messenger will send +initialize again after this // procedure finishes. Of course, if this is not being called // from the messenger then it won't happen. 2778172 }
retry: runtimeLock.assertReading();
// 尝试获取这个类的缓存 imp = cache_getImp(cls, sel); if (imp) goto done;
// Try superclass caches and method lists. { unsigned attempts = unreasonableClassCount(); // 循环获取这个类的 缓存IMP 或 方法列表的IMP for (Class curClass = cls->superclass; curClass != nil; curClass = curClass->superclass) { // Halt if there is a cycle in the superclass chain. if (--attempts == 0) { _objc_fatal("Memory corruption in class list."); }
// Superclass cache. // 获取父类 缓存的IMP imp = cache_getImp(curClass, sel); if (imp) { if (imp != (IMP)_objc_msgForward_impcache) { // Found the method in a superclass. Cache it in this class. // 如果发现父类的方法,并且不再缓存中,在下面的函数中缓存方法 log_and_fill_cache(cls, imp, sel, inst, curClass); goto done; } else { // Found a forward:: entry in a superclass. // Stop searching, but don't cache yet; call method // resolver for this class first. break; } }
// No implementation found. Try method resolver once.
// 如果没有找到,则尝试动态方法解析 if (resolver && !triedResolver) { runtimeLock.unlockRead(); _class_resolveMethod(cls, sel, inst); runtimeLock.read(); // Don't cache the result; we don't hold the lock so it may have // changed already. Re-do the search from scratch instead. triedResolver = YES; goto retry; }
// No implementation found, and method resolver didn't help. // Use forwarding.