/** * Initialize a fresh weak pointer to some object location. * It would be used for code like: * * (The nil case) * __weak id weakPtr; * (The non-nil case) * NSObject *o = ...; * __weak id weakPtr = o; * * @param location Address of __weak ptr. * @param newObj Object ptr. */
id objc_initWeak(id *location, id newObj) { // 查看对象实例是否有效 // 无效对象直接导致指针释放 if (!newObj) { *location = nil; return nil; } return storeWeak(location, (objc_object*)newObj); }
id objc_storeWeak(id*location, idnewObj) { id oldObj; SideTable *oldTable; SideTable *newTable; ...... // Acquire locks for old and new values. // Order by lock address to prevent lock ordering problems. // Retry if the old value changes underneath us. retry: oldObj = *location; oldTable = SideTable::tableForPointer(oldObj); newTable = SideTable::tableForPointer(newObj); ...... if (*location != oldObj) { OSSpinLockUnlock(lock1); #if SIDE_TABLE_STRIPE > 1 if (lock1 != lock2) OSSpinLockUnlock(lock2); #endif goto retry; } if (oldObj) { weak_unregister_no_lock(&oldTable->weak_table, oldObj, location); } if (newObj) { newObj = weak_register_no_lock(&newTable->weak_table, newObj,location); // weak_register_no_lock returns NULL if weak store should be rejected } // Do not set *location anywhere else. That would introduce a race. *location = newObj; ...... return newObj; }
if (oldObj) { weak_unregister_no_lock(&oldTable->weak_table, oldObj, location); } if (newObj) { newObj = weak_register_no_lock(&newTable->weak_table, newObj,location); // weak_register_no_lock returns NULL if weak store should be rejected }
void *objc_destructInstance(idobj) { if (obj) { // Read all of the flags at once for performance. bool cxx = obj->hasCxxDtor(); bool assoc = obj->hasAssociatedObjects();
// This order is important. if (cxx) object_cxxDestruct(obj); if (assoc) _object_remove_assocations(obj); obj->clearDeallocating(); } return obj; }