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

?

+2


source to share


1 answer


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.

+9


source







All Articles