SideTables
The weak reference table is a hash table, which is a map stored in key-value format. You can find more details about SideTable by searching the source code.
To be clear, SideTables and SideTable are two different data structures, so let’s take a look at SideTables
Search for SideTables in the source code to find its definitions.
As you can see, SideTables is a global static variable of type StripedMap
that actually calls the sidetablesmap.get () function, which is defined in the OBJC ::ExplicitInit class.
Let’s seeStripedMap
It’s a structure.
The StripedMap is a generic structure. It is a void* -> T Map. In other words, it is a hash table with a void* key and a value of T. In the red box above, we can see that the code defines the StripeCount variable, which is 8 on the IPhone and 64 on other platforms. We can see what this variable does in the following code.
As you can see, the StripeCount variable is used to create an array of type PaddedT. SideTables is actually a hash table that stores variables of type T. It calculates the hash value of the pointer using indexForPointer. (addr >> 4) ^ (addr >> 9)) % StripeCount; SideTables(); SideTables(); SideTables(); SideTables(); SideTables(); On other platforms, the length is 64, so there are 64 sidetables.
Let’s take a look at the structure of the SideTable.
SideTable
Search for SideTable in the source code to find the structure definition of SideTable.
There are only three variables in the structure, respectively spinlock_t type spinlock, used to lock to prevent data race problems caused by multithreading operations; The reference counting table of type RefcountMap and the weak reference table of type Weak_table_t have been analyzed in previous articles.
Weak table insert weak table insert weak table insert weak table insert weak table insert weak table insert weak table insert weak table
Weak table and sidetable
SideTable[obj]; SideTable[obj]; SideTable[obj]; SideTable[obj]; SideTable[obj]; Weak_table (sideTable -> Weak_table); weak_table (sideTable -> Weak_table); Weak_table (sideTable -> Weak_table);
Weak reference Table (SideTable); Weak reference Table (SideTable); Weak reference Table (SideTable); Weak reference Table (SideTable) That is, there are at most 8 sidetables and 8 Weak tables in IPhone real machine, and there are at most 64 sidetables and 64 Weaktables in other platforms. The same is true for reference counting tables. These scattered tables stored through hash tables together form a generalized global weak reference table/reference count table.
Retain and Release
Retain
After sorting out the relationship between SideTables, SideTable, and weak reference tables and reference counting tables, let’s take a look at the Retain and Release methods.
In MRC, a call to Retain causes the object’s reference count to +1, and a call to Release causes the object’s reference count to -1. When the reference count reaches 0, the object is released by the system.
Start by searching for retain in the source code.
You can see that the retain method actually just calls the _objc_rootRetain(self) method, passing the object into the function via self.
Here we skip one of the private methods in the middle and go straight to the final rootRetain() function.
As you can see, the code in rootRetain that is associated with SideTable and performs the related retain operation is in the red box above, where it is divided into sidetable_tryRetain and sidetable_retain methods.
Next, let’s go into the sideTable_retain method to see how it is implemented.
SideTables() is a static variable. SideTables() is a static variable. SideTables() is a static variable. SideTables() is a static variable. The syntax of SideTables()[this] is used to retrieve the object’s SideTable.
SideTable contains three attributes: spin lock, reference count table, and weak reference table. The retain operation is performed here, so the table is locked first, and the reference count corresponding to the object is retrieved by table.refcnts[this]. You can see from this that the reference counter table is actually a hash table.
Retain incremented the reference count of the object by one and released the spin lock of the SideTable.
Release
Now let’s look at the implementation of Release. Again, the first step is to figure out how to implement Release in your code.
You can see that the key code in the objc_object::rootRelease function is the sideTable_release () function, which is responsible for counting the object’s reference to -1. Objc_object ::rootRelease(bool performDealloc, bool handleUnderflow) The first parameter, as you can see from the name, identifies whether the object should be released after it has been released.
Sidetable_release (SideTables); SideTable (SideTables); do_dealloc (SideTable); SideTables (SideTables); The object’s reference count is set to SIDE_TABLE_DEALLOCATING and the dealloc method of the object is finally called with objc_msgSend, and the release method is executed.
Write in the last
After exploring and learning SideTables and SideTable, I further deepened my understanding of the previous weak table. SideTable concatenates reference counting tables, weak reference tables, and provides a deeper understanding of retain and release in memory management.
Tino Wu
more at tinowu.top