Lokang 

Swift and MySQL

automatic referencing counting

Automatic Reference Counting (ARC) is the memory management strategy used by Swift to track and manage your app’s memory usage. ARC automatically keeps track of the number of references to each instance of a class and deallocates memory for instances that are no longer needed. While ARC is automatic, you still need to ensure that you don't create strong reference cycles, as this can lead to memory leaks.

Basic Operation

Every time you create a new instance of a class, ARC allocates a chunk of memory to store information about that instance. This memory holds information about the instance's type, its properties, and other information.

When an instance is no longer needed, ARC frees up the memory so that it can be used for other purposes. To make sure that an instance is not deallocated while it is still needed, ARC tracks the number of active references to each instance.

For example:

class Dog {
   var name: String
   init(name: String) {
       self.name = name
       print("\(name) is being initialized.")
   }
   deinit {
       print("\(name) is being deinitialized.")
   }
}
var myDog: Dog? = Dog(name: "Fido")  // "Fido is being initialized" is printed
myDog = nil  // "Fido is being deinitialized" is printed

Strong Reference Cycles

A strong reference cycle occurs when two class instances hold a strong reference to each other, causing a memory leak because neither instance can be deallocated.

To avoid strong reference cycles, you can use weak or unowned references:

Weak References: A weak reference doesn't keep a strong hold on the instance it refers to, and it doesn't prevent ARC from disposing of the referenced instance. It is always declared as an optional type.

Unowned References: Like a weak reference, an unowned reference doesn’t keep a strong hold on the instance it refers to. Unlike a weak reference, an unowned reference is used when the other instance has the same or longer lifetime. It is not an optional and must always have a value.

Here is an example demonstrating weak and unowned to avoid a strong reference cycle:

class Person {
   let name: String
   init(name: String) { self.name = name }
   var apartment: Apartment?
   deinit { print("\(name) is being deinitialized") }
}
class Apartment {
   let unit: String
   init(unit: String) { self.unit = unit }
   weak var tenant: Person?
   deinit { print("Apartment \(unit) is being deinitialized") }
}
var bob: Person? = Person(name: "Bob")
var apt: Apartment? = Apartment(unit: "1A")
bob?.apartment = apt
apt?.tenant = bob
bob = nil
apt = nil

Strong Reference Cycles for Closures

Closures can capture and store references to variables and constants from the surrounding context in which they are defined. If a closure captures a class instance, it creates a strong reference to that instance, leading to the possibility of a strong reference cycle.

You can use a capture list to break strong reference cycles involving closures:

class SomeClass {
   var name: String = "Hello"
   lazy var closure: () -> String = { [weak self] in
       return self?.name ?? "default"
   }
}

Here, [weak self] tells Swift to capture self as a weak reference within the closure.

Summary

ARC works well to manage memory in most situations without requiring explicit cleanup code. However, it's essential to understand how to break strong reference cycles between class instances or between an instance and a closure to prevent memory leaks.