ARC, stands for “Automatic Reference Counting”. Its main purpose is to manage app memory management. Its means we do not have to think about memory management. ARC automatically frees the memory which is used by class instance, when the instance is no longer used.
It is applied to the class instance as it is a reference type. It is not applied to Structure or Enumerator as it is a valued type.
ARC automatically manages the memory but sometimes it required more information about our code to manger memory.
Working of ARC
It works in such a way that, every time when a new class instance is created, it allocates a chunk of memory. The memory holds the instance information. When the class instance is no longer in used then ARC free the memory. If ARC has to deallocate the memory whose instance is in use, in that case, you can not access the instance property or method. If you will try to access them in that case your app will crash.
To make sure that this does not occur, ARC tracks the constant, variable, and property referring to the class instance. If at least anyone is in used then ARC does not deallocate the memory. It is possible because of strong references.
Let takes an example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
class Employee{ let empId:String let empName:String init(empId:String, empName:String){ self.empId = empId self.empName = empName print("being initialized") } deinit{ print("being deinitialized") } } var emp: Employee? emp = Employee(empId: "E001", empName: "Raj")// being initialized |
The above class contains the initializer and Deinitializer, the Deinitializer is called when the instance is deallocated.
When the Employee class is initialized then it prints being initialized.
1 2 3 4 5 6 7 |
var emp1: Employee? var emp2: Employee? emp1 = emp emp2 = emp emp1 = nil emp2 = nil emp = nil // being deinitialized |
Now, we have created two-variable emp1 and emp2 of Employee? type and it is initially nill. We have assigned these variables with emp. And now when we set it to nil then Arc deallocate this instance.
Note:- In the above example ARC does not deallocate the instance until all the variable strong reference is broken.
strong, weak, unowned references
i) strong- It is a default reference. When the class instance is assigned to constant or variable then it makes a strong reference.
ii) weak- It is a reference that does not make a stronghold on the reference. Weak reference can be indicated by placing a weak keyword before a property or variable declaration.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
class Employee{ let empId:String let empName:String var company: Company? init(empId:String, empName:String){ self.empId = empId self.empName = empName print("Employee being initialized") } deinit{ print("Employee being deinitialized") } } class Company { let name: String init(name: String) { self.name = name print("Company being initialized") } weak var emp: Employee? deinit { print("Company being deinitialized") } } var emp: Employee? var comp: Company? emp = Employee(empId:"emp001", empName:"Raj") comp = Company(name: "ABC") emp!.company = comp comp!.emp = emp emp = nil comp = nil |
When we run the above example we get
1 2 3 4 |
Employee being initialized Company being initialized Employee being deinitialized Company being deinitialized |
iii) unowned – It also does not make a stronghold on the reference. It is indicated by placing an unowned keyword before a property or variable declaration. ARC does not set the value to nil.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
class Employee{ let empId:String let empName:String var company: Company? init(empId:String, empName:String){ self.empId = empId self.empName = empName print("Employee being initialized") } deinit{ print("Employee being deinitialized") } } class Company { let name: String unowned var emp: Employee init(name: String, emp: Employee) { self.name = name self.emp = emp print("Company being initialized") } deinit { print("Company being deinitialized") } } var emp1: Employee? var comp: Company? emp1 = Employee(empId:"emp001", empName:"Raj") emp1!.company = Company(name: "Abc", emp: emp1!) emp1 = nil |
When we run the above example we get
1 2 3 4 |
Employee being initialized Company being initialized Employee being deinitialized Company being deinitialized |
You can also check other blogs from here. if you have any issue or suggestion you can leave your query/suggestion in the comment section.