To prepare

This article continues the memory management series on weak references. In normal development we often use the __weak modifier to result in circular reference problems during development. Since the __weak modifier object reference count does not increase, this article will analyze how __weak is implemented from the perspective of the underlying source code.

Breakpoint debugging

Breakpoint debuggingAlways display disassembly debugging information debug->show->always show disassembly

Call the objc_initWeak method

Why is objc_initWeak called?This is mainly done when LLVM is compiled__weakMatch to theobjc_initWeakSymbols. You can verify this in the LLVM source code, as shown below

The source code to achieve

Search for objc_initWeak in objc source code

objc_initWeak

  • First check whether the called object is empty, if empty directly return
  • Objc_initWeak (&weakObjc,objc), can be directly understood
  • StoreWeak is called, which is a highly wrapped method in time, and is also called when objc_destroyWeak destroys it. This method passes template parameters.

//haveOld: the value is true, indicating that it needs to be cleaned up in time
//haveNew: true, needs a new value to replace
// If CrashifDealLocation is true, the process will stop if newObj is Deallocating, or if the newObj class doesn't support weak references.
// If crashifDealLocation is false, nil is stored.
Copy the code

storeWeak

Enter the source: the first step, according to the object to obtain oldTable and newTable tableStep 2: Lock the table for thread-safe processing,locationShould be the sameoldObjKeep consistent, if different, indicate currentlocationHas been treatedoldObjHowever, it is modified by other threads to ensure thread safety. This judgment is used to avoid thread collision reprocessing problemsStep 3: Make sure that the initialization of the class referring to the object is completeStep 4: If the value is old, remove the old value from the weak reference tableStep 5: Insert the new value into the corresponding weak reference table, and then passsetWeaklyReferenced_nolockMethod is marked with the corresponding weakly referenced object.

weak_register_no_lock

This method essentially inserts the weak-reference object into the corresponding weak-reference table.

Step 1: Check if it is tagged Pointer or nil, if it is returned directly.

Step 2: Determine whether the object is positive or notdeallocMake sure the object is availableStep 3: Add

There’s a judgment here, if there was a prior prior correspondingentry“Is directly added. If not, add it after creating it.

Append_referrer (add)

Step 1: Store inlineSecond, if inline is full, store it in outline and store inline data in outline as wellStep 3: Outline Expand the capacity when it reaches 3/4 of the capacity

Weak reference release

As mentioned in the previous iOS memory management article (Nonpointer_isa+ hash +retain+release), objects actually have a weakly_referenced identifier. Weakly_referenced, To distinguish between objc_clear_deallocating – > clearDeallocating

callweak_clear_no_lock

Weak reference structure diagram

The following is a diagram to summarize the structure of the weak reference table for easy understanding

  • First we have a global variable with eight of themsideTable(Real plane). throughobjectObject can find the correspondingsideTabe.
  • sideTableThere’s one in thereweak_table_t.weak_table_tThere’s one stored in thereweak_entry_tCan be retrieved from objectweak_entry_t. An object and aweak_entry_tThe corresponding
  • An object may have multiple weak references, and weak reference objects are stored inweak_entry_ttheinlineoroutlineinside

I believe you have a more comprehensive understanding of weak references, which is more conducive to our understanding of the source code.