The original address: www.jishudog.com/8744/html

Memory layout

Memory layout for iOS applications

The meanings of different memory layout areas stack method call object allocated by alloc etc. BSS uninitialized global variable data initialized global variable text program code

Memory management scheme

  • taggedPointer
  • NONPointer_ISA
  • Hash table (very complex data structure, reference count table, weak reference table)
Hash table
  • SideTables() (64 SideTables on non-embedded systems) is actually a hash table. The pointer to the object is used to find the corresponding reference counting table or weak reference table. In which SideTable is found
  • The SideTable structure contains the spinlock reference count table weak reference table
  • Why not a SideTable? There is an efficiency problem, if multiple objects are counting references to the same table, they will wait for the previous object operation to end before they can operate. Use separate locks to improve efficiency
  • How to achieve fast triage? A uniform hash function evaluates the array index based on the address of the object

Data structure in a hash table

  • Spinlock (Spinlock_t) is a busy lock (the current lock has been acquired by other threads, and the lock is constantly detected to see if it has been released) suitable for light access
  • Reference Count table (RefcountMap) PTR — > DisguisedPtr(obj) — >size_t Improves the search efficiency, the insert and the get are both through the same hash algorithm, avoiding array traversal
  • Weal_table_t PTR — > Hash function — >value

ARC&&MRC

  1. MRC manual reference counting
    • alloc
    • retain
    • release
    • retainCount
    • autorelease
    • dealloc

2.ARC automatic reference counting

  • ARC is the result of a collaboration between LLVM and Runtime
  • ARC disallows manual calls to retain, Release, retainCount, dealloc
  • Added the weak and strong attribute keywords in ARC

Reference counting

  • Alloc goes through a series of calls to the C function malloc, which does not set the reference count to 1.

  • Retain hashes twice to find the reference count and then +1

  • Release hashes twice to find the reference count, and then performs -1

  • RetainCount hashes twice to find the reference count value and adds it to 1 (so the object just alloc doesn’t actually have this mapping in the reference count table)

  • dealloc

    Judge the conditions that can be released (one of the five conditions is indispensable)

    • Nonpointer_isa is not used
    • There is no weak pointer to it
    • There is no associated object
    • No ARC or C++ involved
    • The reference count for the current object is not stored through the reference count table in SideTable

[Image upload failed…(image-584a89-1608785619322)]

Object_dospose () function internal implementation analysis

ClearDeallocating () is an internal implementation

A weak reference

The process of adding the weak variable

How to add the weak variable? Object pointer is called objc_initweak() after compiler compilation, then storeweak() method, through a series of function calls, and finally weak-reference variable is added in Weak_register_no_lock (), through hash algorithm location search, If an array of weak references corresponds to the current object already exists, the weak pointer is directly added to the array. If not, a new array of weak references is created to store the weak pointer

How does the system set the abandoned weak pointer to nil

How does the system set the abandoned weak pointer to nil? When an object is deprecated by dealloc, the related function for weak reference clearance is called. Then in the function implementation, according to the current object pointer, look up the weak reference table, take out the weak reference corresponding to the current object, and then iterate over all the weak reference pointer set to nil

Automatic release tank

How does AutoreleasePool work?

AutoreleasePool is a data structure consisting of a stack node and a bidirectional linked list. The compiler overwrites **@autoreleasepool{}** as shown below. The actual objc_autoreleasePoolPop function does a pop operation internally, batch releasing all autoReleasepool objects

Compiler overwrite @autoreleasepool{}

A brief explanation of the main functions above is given below

The structure of AutoreleasePool
  • Is a stack node through the form of bidirectional linked list combination
  • It’s one to one for threads

What is a bidirectional list?

Bidirectional linked list structure

[obj autoRelease] implementation (object added to automatic release pool)

Check whether the current next pointer points to the top of the stack, if not directly added; If so, add a stack node to the linked list and add objects to the new stack; Move the next pointer

AutoreleasePoolPage: : push implementation process (free pool multilayer nested)
  • Insert sentry object

AutoreleasePoolPage:: POP Implementation flow (as opposed to push)
  • Locate the corresponding position based on the incoming sentry object
  • Add release messages to the objects added after the last push operation
  • Roll back the next pointer to the correct position
Why can AutoreleasePool be nested?

Multiple insertion of the sentinel object, that is, the creation of a new releasePool, does not require the creation of a new page if the current stack is not full; if it is, a new stack node is added

In the figure below, when is the array object released?

A: Call AutoreleasePoolPage: POP () when the runloop is about to end torelease the array object

How do you use AutoreleasePool?

In the for loop, autoreleasePool is manually inserted for scenarios with high memory consumption, such as alloc image data. Each for loop is released once to reduce memory consumption

A circular reference

  • Self-circular reference
  • Cross reference
  • Multiloop reference

Self-circular references hold strong on themselves

Cross reference

Multiloop reference

Common circular references and breaking methods:
  • Delegate
  • block
  • NSTimer
  • Macrocyclic reference
How do I break circular references?
  • Avoid circular references
  • Manually break the loop when appropriate
What are the specific solutions?
  • __weak
  • __block
  • __unsafe_unretained(same as weak)
The difference between __block in ARC and MRC conditions
  • Under MRC, __block modifier objects do not increase their reference count, avoiding circular references
  • In ARC, __block modifier objects are strongly referenced, which is unavoidable and requires manual breaking
__unsafe_unretained crack
  • Modifier objects do not increase their reference count, avoiding circular references
  • Creates a dangling pointer if the modifier object is released in a deed
Examples of circular references? (Do you encounter cyclic references during development and how to solve them?)
  1. Block usage examples (later in the Block tutorial)
  2. NSTimerd circular reference problem

This is the end of the article, you can also message me to get timely interview information. If you have any comments and suggestions, please leave a message to me.