SoFunction
Updated on 2025-04-11

Detailed discussion on reference counting in swift memory management

In swift, each object has a life cycle. When the life cycle ends, the deinit() function will be called to free up memory space.

Observe this code:

class Person{
 
 var name: String
 var pet: Pet?
 
 init(name: String){
   = name
  print("Person", name, "is initialized")
 }
 
 init(name: String, petName: String){
   = name
   = Pet(name: petName)
  print("Person", name, "is initialized")
 }
 
 deinit{
  print("Person", name, "is deinitialized!")
 }
}

class Pet{
 
 var name: String
 init(name: String){
   = name;
  print("Pet", name, "is initialized")
 }
 
 deinit{
  print("Pet", name, "is deinitialized!")
 }
}

This code creates two classes, namely the Person class and the Pet class. Each class has an init method to create objects and deinit methods to free up memory space. There are two init methods in the Person class, which correspond to whether the name of the Pet class is contained.

When we call these two methods:

var snow: Person? = Person(name: "snow", petName: "wolf")
snow = nil

The two-step execution results are:

Pet wolf is initialized
Person snow is initialized
Person snow is deinitialized!
Pet wolf is deinitialized!

You will find that when creating the snow object, the second init method is called. In this method, a new Pet object will be created, so Pet wolf is initialized and then Person snow is initialized. When the snow object is released, nil is assigned to this object, the snow memory space will be released, and the wolf memory space will be released.

But if we call the first init method we will find:

var snow: Person? = Person(name: "snow")

var wolf: Pet? = Pet(name: "wolf")
snow?.pet = wolf

snow = nil
wolf = nil

We first create a snow object, then create a wolf object, and then add wolf to the snow object, but when we release the snow object memory, we will find:

Person snow is initialized
Pet wolf is initialized
Person snow is deinitialized!

Only snow's memory space is freed, but wolf's memory space is not freed. This is related to the reference count in swift memory management:

After we create the snow object, we open up a memory space for it and name it a. At this time, the snow object refers to this memory space, and the reference count of this memory space is 1.

Similarly, after we create the wolf object, we open up a memory space for it, named b. At this time, the wolf object refers to this memory space, and the reference count of this memory space is 1.

After we turn snow?.pet = wolf, then a property in snow also points to the memory space where the object of wolf is created, and the reference count of this memory space is 2.

When we release the memory space of snow = nil, the reference count of memory space a is 0, and the reference count of memory space b is 1.

When the system finds that the reference count of a memory space is 0, the system will release the memory space, and the memory space a is released.

However, the reference count of memory space b is 1, and the system will not automatically release memory. Only when we do:

wolf = nil

After operation, this memory space b will be released.

Similarly for such code:

import UIKit

class Person{
 
 var name: String
 
 init(name: String){
   = name
  print("Person", name, "is initialized")
 }
 
 deinit{
  print("Person", name, "is being deinitialized!")
 }
}

var person1: Person? = Person(name: "liuyubobobo")
var person2: Person? = person1
var person3: Person? = person1

Then the reference count of person1's memory space is 3. If this memory space is released, all three objects need to be nil

If you just change person1=nil, this memory space will not be released.

The above article details the reference counting in swift memory management is all the content I share with you. I hope you can give you a reference and I hope you can support me more.