记录/objc2/object_setClass做了啥
inline Class objc_object::changeIsa(Class newCls) { // This is almost always true but there are // enough edge cases that we can't assert it. // assert(newCls->isFuture() || // newCls->isInitializing() || newCls->isInitialized()); assert(!isTaggedPointer()); isa_t oldisa; isa_t newisa;+构建新对象体 isa_t bool sideTableLocked = false; bool transcribeToSideTable = false; do { transcribeToSideTable = false; oldisa = LoadExclusive(&isa.bits); if ((oldisa.bits == 0 || oldisa.nonpointer) && !newCls->isFuture() && newCls->canAllocNonpointer()) { // 0 -> nonpointer // nonpointer -> nonpointer #if SUPPORT_INDEXED_ISA if (oldisa.bits == 0) newisa.bits = ISA_INDEX_MAGIC_VALUE; else newisa = oldisa; // isa.magic is part of ISA_MAGIC_VALUE // isa.nonpointer is part of ISA_MAGIC_VALUE newisa.has_cxx_dtor = newCls->hasCxxDtor(); assert(newCls->classArrayIndex() > 0); newisa.indexcls = (uintptr_t)newCls->classArrayIndex(); #else
if (oldisa.bits == 0) newisa.bits = ISA_MAGIC_VALUE; else newisa = oldisa; // isa.magic is part of ISA_MAGIC_VALUE // isa.nonpointer is part of ISA_MAGIC_VALUE newisa.has_cxx_dtor = newCls->hasCxxDtor(); newisa.shiftcls = (uintptr_t)newCls >> 3;+改变类型的指针,存储的时候清除低位没用的3位
#endif } else if (oldisa.nonpointer) { // nonpointer -> raw pointer // Need to copy retain count et al to side table. // Acquire side table lock before setting isa to // prevent races such as concurrent -release.
+如果是TargetPoint对象,标记为需要转移其他数据 if (!sideTableLocked) sidetable_lock(); sideTableLocked = true; transcribeToSideTable = true; newisa.cls = newCls; } else { // raw pointer -> raw pointer newisa.cls = newCls; }
+上面在为新对象体转移数据 } while (!StoreExclusive(&isa.bits, oldisa.bits, newisa.bits));+将数据覆盖对象体,内部原子的比较并交换 if (transcribeToSideTable) { // Copy oldisa's retain count et al to side table. // oldisa.has_assoc: nothing to do // oldisa.has_cxx_dtor: nothing to do
+被标记为转移其他数据,转移引用计数器-1标识,转移是否正在dealloc的标识,转移所引用标识 sidetable_moveExtraRC_nolock(oldisa.extra_rc, oldisa.deallocating, oldisa.weakly_referenced); } if (sideTableLocked) sidetable_unlock(); if (oldisa.nonpointer) { #if SUPPORT_INDEXED_ISA return classForIndex(oldisa.indexcls); #else return (Class)((uintptr_t)oldisa.shiftcls << 3); #endif } else { return oldisa.cls; } }