How does the Objective-C runtime know if a low-referenced object is alive?
With the advent of ARC, there are some new features that allow developers to play with loosely coupled objects. id objc_loadWeak(id *location)
is one of them. This function takes one parameter corresponding to another location in memory where the weak object was stored, and returns that object if it is still alive or nil
if it was freed.
It looks like when an object obj
is stored as weak
in location location
c id objc_storeWeak(id *location, id obj)
, it obj
is placed in the "weak map", and location
- as a key. However, to get obj
, it objc_loadWeak
can not only use location
as a key, but also return a value that matches obj
. He must also check if he is alive in obj
order to return nil
if he is no longer found.
However, objc_loadWeak
it cannot try to read the object's persistence count because the object might be deallocated. Furthermore, although a weak card objc_storeWeak
, objc_loadWeak
and class NSObject
are implemented in a single file ( NSObject.mm ), NSObject
dealloc
does not signal a weak card, that an object that is freed and leaves.
So how does the Objective-C runtime determine if an object remains weak
?
source to share
The NSObject dealloc method does not signal the weak map that the object that is being deallocated is gone.
He does.
- [NSObject dealloc]
challenges
_objc_rootDealloc(self);
which in turn calls
object_dispose()
which in turn calls
objc_destructInstance()
which finally calls
objc_clear_deallocating()
This last function looks like this:
void
objc_clear_deallocating(id obj)
{
assert(obj);
assert(!UseGC);
SideTable *table = SideTable::tableForPointer(obj); /* *** THIS LINE *** */
// clear any weak table items
// clear extra retain count and deallocating bit
// (fixme warn or abort if extra retain count == 0 ?)
OSSpinLockLock(&table->slock);
if (seen_weak_refs) {
arr_clear_deallocating(&table->weak_table, obj); /* *** THIS LINE *** */
}
table->refcnts.erase(DISGUISE(obj)); /* *** THIS LINE *** */
OSSpinLockUnlock(&table->slock);
}
The three highlighted lines do the magic. SideTable
is a C ++ class implemented in NSObject.mm
, from which a member variable refcnts
does exactly what it sounds like: it contains reference counting.