Take weak and __weak as the incision, and have a deeper understanding of the mechanism of them and the weak table behind.

Weak and Weak form

The weak table is a hash table governed by a single spin lock.An allocated blob of memory, most often an object, but under GC any such allocation, may have its address stored in a __weak marked storage location through use of compiler generated write-barriers or hand coded uses of the register weak primitive. Associated with the registration can be a callback block for the case when one of the allocated chunks of memory is reclaimed. The table is hashed on the address of the allocated memory. When __weak marked memory changes its reference, we count on the fact that we can still see its previous reference.So, in the hash table, indexed by the weakly referenced item, is a list of all locations where this address is currently being stored.

This is the definition of the weak table in the objc_weak.h header file of objC4-781. What’s the weak table? To answer this question we need to think of the weak or __weak modifier commonly used in development. In development, it is common to prevent problems such as memory leaks in delegate usage by using weak in the modifier defined in the delegate property. This will solve the memory leak problem caused by cyclic references when using the proxy. Alternatively, if we have a UI control that is no longer needed after it has been shown once in the interaction, we can define weak so that it automatically sets nil when it is removed from the layer, reducing memory footprint. But behind the scenes of this mechanism is how the weak table works, and why objects that are labelled weak or __weak can be set to nil automatically.

The source code to define

First let’s take a lookweak tableDefinition in the source code.You can seeweak tableThe structure of alpha is not too complicatedweak_entry_tType, which is the entry to the weak reference,num_entriesRepresents the size of the table, in additionmaskandmax_hash_displacementThe two variables are mainly related to the mask and hash offset. As you can see from the comments in the source code,weak tableIn order toobject idsAs the keys of the hash tableweak_entry_tAs values of the hash table. So let’s seeweak_entry_tWhat the structure looks like.Among them,DisguisedPtrHere’s the definition of

As you can see, the DisguisedPtr class encapsulates the pointer to the generic object. The Referrers of the Weak_entry_T structure is the pointer of weak_Referrer_T, that is, the two-dimensional pointer to DisguisedPtr

, So it is a two-dimensional array of DisguisedPtr< objC_object *>. A weak reference hash is made by using a two-dimensional pointer address offset and a subscript as the hash key. This is why weak tables are the source of hash tables, and weak reference tables are static hash table structures.

Weak object insert

inNSObject.mmWe can find it in the fileStoreWeakMethod implementation,StoreWeakMethods byobjc_initweakMethod call.

As you can see, in the StoreWeak method, the Weak_register_no_lock method is the key way to add weak references to the weak table, before all the necessary locking and other operations.

inweak_register_no_lockMethod, the method body is built with weak referencesreferent, its property is aobjc_objectObject.

After thereferentAfter filling in the relevant information, it is time to start the insert operation.

Weak_entry_t *entry is first defined, and weak_entry_for_referent() is used to try to obtain the weak_entry_for_referent() entry of the object. If the weak_entry_for_referent() method is obtained, it indicates that the object has existed in the weak table before. Then expand in weak_entry_T. If not, it indicates that the weak reference object is added to the weak table for the first time. Else branch is executed in the code, and after creating a Weak_entry_t, weak_entry_INSERT method is used to insert it into the global Weak_TABLE.

At this point, a weak object has been successfully added to the weak table. Through this process, we can have a clearer understanding of the operation mechanism of weak table and verify the fact that weak table is a hash table with object as key and Weak_entry_t as value.

Other related methods

We are inweak_table_tYou can see that in the definition of the structureobjc_weak.hFour interfaces are exposed externally, including registering and inserting objects to weak table, deregister and removing objects, finding whether weak reference objects are in the table, and setting all weak reference Pointers of the object to nil. These methods are key to the operation of the whole weak table, as well as internal methods such as expansion of the weak table.

Since then, __weak obj1 = obj; The running process of this line of code has been completely carded.

Write in the last

In general, weak table implementation is not too complicated. It has several key data structures such as Weak_table_T, Weak_entry_t,DisguisedPtr

. Weak_register_no_lock, Weak_unregister_no_lock,weak_entry_insert,append_referrer and other key methods. One more detail, can from the objc_weak objc4 source. J h, objc_weak. Mm, NSObject. J h, NSObject. Mm, such as access to the file.

If there are mistakes, welcome readers to put forward.


Tino Wu