Uncategorized
Image for post
Memory debug image

If you know about what ARC is and why it leaks memory in the IOS application then you can move on to part 2. Since this is a very long article, referring to the following:

  1. What is a memory leak in IOS(Memory Leaks)
  2. Why Memory Leaks
  3. How ARC can't free up memory
  4. Memory Leaks in the Closure function
  5. Possible solutions
  6. Singleton and static Classes Memory leaks
  7. Differences between weak and unowned
  8. Identifying Leaks Using Memory Graph Debugger
  9. Some Thumbs Rules

Swift uses Automatic Reference Counting(ARC) to track and manage application memory. In most cases, this means that management only works in swift framework automatically, and you don't need to understand how memory management works. ARC automatically frees up memory because when 1 instances of the class will release when it is no longer needed.

Part 1: Memory leaks in IOS

A memory leak occurs when memory is occupied and cannot be released using ARC because it does not distinguish if it is actually used or not. And the most common problem is that we create memory leaks when creating a loop of cycles – mutual holding happens! We'll take a closer look at it below.

When can ARC not free up memory?

Each time you create an object from the class, arc saves information about the memory area that this object uses. When an object needs to be released, how does the ARC know it. To understand this issue we will learn how arc works.

Any initial variable will default to a strong type. (strong is a strong, weak type of constraint). When you create its instance with a strong type, the ARC increases the counting variable to 1. Understand that arc produces 1 variable count = 0, when obj creates it increases to 1, when released, minus 1. Ever this count variable = 0 means that it is no longer needed, and the ARC will automatically release this variable. Let's see the following example:

var referenceOne: Person? = Person()

we create a referenceOne of the Person class. Arc will automatically give it strong memory and increase its count to 1.

Image for post
When initialing an object
var reference2 = referenceOne

After performing the above statement, we create a strong link to the Object Person by assigning the address to reference2. As you can see in the following image, the count = 2 variable is held by two guys with this address.

Image for post
both assign to the initialed object
referenceOne = nil

We remove the strong reference to the referenceOne variable by assigning nil to it. As pictured after the turn back is 1.

Image for post
reference2 = nil

Similarly, we ignore the strong reference reference to the reference2 variable and the current variable count = 0.

Thus, if the created object has no one to refer to, the ARC will delete from the memory. That's how arc works.

So why does memory leak?

As we understand arc will automatically delete the variable from memory when count = 0, but for some reason count never = 0, so it is impossible to free up memory. Read on!

When does arc try to check the count of 1 RC variable(reference count)

When you work with cocoa or cocoa touch, it simply checks when a function exits the loop on the thread. The law on inspection is as follows:

  • If no one references an object, arc frees
  • If an object does not have a strong reference to it.

Here's a specific example:

Image for post
var user: User? = User() //1 reference to user
Var todo: Todo? = Todo() //1 reference to todo

As shown below, ARC makes a strong reference to the user and todo.

Image for post
user?. todo = todo //2 strong reference to todo
todo?. associatedUser = user// 2 strong reference to user

The above 2 commands work as follows:

  • Increase the RC of the todo todo to 2, the todo has 2 owners, 1 creation and 1 assignment.
  • Increase the RC of the user to 2, similar to the above.
Image for post
user = nil //decrease the RC of the user to 1
todo = nil //reduce RC of todo todo to 1

Ideally, when placing users on nil, RC should be 0. However, at this time, each object is strongly referenced to each other, so it cannot be released. And so we create a strong reference cycle – a circle of strong mutual reference that cannot be released.

Image for post

solution

There are two solutions, using weak references or unowned references.

Revise the code as follows:

Image for post
var user: User? = User() //RC = 1 to user
Var todo: Todo? = Todo() //RC = 1 to todo

The above statement increases the RC for each variable to 1.

Image for post
user?. todo = todo //RC = 2 todo
todo?. associatedUser = user //RC = 1 to user

RC = 2 strong references to todo, while users with RC = 1 because associatedUser is a weak reference.

user = nil

The user's RC statement is about 0.

Image for post

ARC checks and removes the user from memory. So the todo has a strong reference to it.

Image for post
todo = nil

At this time the todo has RC = 0 and is deleted from memory.

Rule: When two objects refer to each other, the reference variable returns weak or unowned.

Memory Leaks in Closure

Memory Leak in Closure = self refers to → object refers to → self

Closure is a function created from within another function (parent function), it can use global variables, local variables of the parent function and its own local variables. And when used, it captures variables and throws them inside its scope.

What is capturing?

Image for post

To work:

  1. We create 2 variables a,b with 2 different values 20 and 30.
  2. We create someClosure and captures a, b by strong reference.
  3. When the someMethodThatTakeClosure method calls closure and it returns 2 total values of a, b captures from the viewDidLoad function. Value is 50

Let's study together in the next article:

Everything you should know about Memory Leaks in IOS(part 2)

User Avatar

Code Toàn Bug

Code nhiều bug nhiều!

Leave a Reply

Your email address will not be published. Required fields are marked *