1. Weak Implementation (1)
  2. Weak implementation (2)
  3. Weak implementation (3)
  4. Weak -&SideTables()[oldObj]

Text to assist the reading

&SideTables()[oldObj] What is this? SideTables(), [oldObj], &. Paste the entry code first

id oldObj;
SideTable *oldTable;

oldObj = *location;
oldTable = &SideTables()[oldObj];
Copy the code

1. UnderstandSideTables()

First, SideTables() is a static function, all of it

static StripedMap<SideTable>& SideTables() {
    return SideTablesMap.get();
}
Copy the code

The body of the function calls the get() method of the global static variable SideTablesMap, which holds all sideTables. The following statement:

static objc::ExplicitInit<StripedMap<SideTable>> SideTablesMap;
Copy the code

You can see that SideTablesMap is a ExplicitInit class under the namespace objc that implements the get() method, as follows

Type &get() {
    return *reinterpret_cast<Type *>(_storage);
}
Copy the code

For those who are not familiar with c++, the following points can be understood basically:

  • c++In the reference&In c + +&In addition to theTake the addressCan also be used asreference. The method returns a reference, which could easily be mistaken for a pointer without c++ roots.
  • c++In the templatetemplateThe genericTypeIs passed in through a template, that isStripedMap.

As you can see from the declaration above, SideTablesMap is a nested template, and StripedMap is a generic of the ExplicitInit template; SideTable is a generic of the StripedMap template.

  • c++The ` reinterpret_cast < new_type > (expression)

It can convert any two types. The new value and the old value (expression) ‘have the same bits.

* returns the saved value of the converted address, so this is not a pointer. Type * is equivalent to StripedMap *, so get() returns an instance of the StripedMap structure.

2. Understand[oldObj]

[] here is an overloading of []

T& operator[] (const void *p) { 
        return array[indexForPointer(p)].value; 
}
Copy the code

IndexForPointer () = oldObj (); indexForPointer() = oldObj (); Returns the value member of the structure, SideTable.

static unsigned int indexForPointer(const void *p) {
        uintptr_t addr = reinterpret_cast<uintptr_t>(p);
        return ((addr >> 4) ^ (addr >> 9)) % StripeCount;
}
Copy the code
 struct PaddedT {
        T value alignas(CacheLineSize);
    };
Copy the code

StripedMap is a table with void *p as key and PaddedT as value.

3. &

SideTables()[oldObj] = SideTable; SideTables()[oldObj] = SideTable; Right on.