ARC (automatic reference counting) in action

I am currently following Apple Documentation . Here is my question:

class Person { let name: String init(name: String) { self.name = name println("\(name) is being initialized") } deinit { println("\(name) is being deinitialized") } } class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() var reference1: Person? var reference2: Person? var reference3: Person? reference1 = Person(name: "John Appleseed") // prints "John Appleseed is being initialized reference2 = reference1 reference3 = reference1 reference1 = nil reference2 = nil } } 

After reference1 is nil , ARC frees the instance and prints "John Appleseed is being deinitialized"

Shouldn't it be freed after reference3 = nil ?

+6
source share
2 answers

The problem here is the issue of volume. We can learn more with breakpoints.

Here we stop before initializing reference1 .
All nil variables are expected:

enter image description here

And after initializing reference1 ?

enter image description here


Ok, skip ahead so that after reference2 and reference3 are set:

enter image description here

All three variables point to the same memory cell, and we see that the initializer works only once. They all point to the same location.

Take a step forward:

enter image description here

reference1 now points to None . This is nil . deinit mmethod was not called and did not print his message.

Take a step further:

enter image description here

Now reference1 and reference2 both expected nil . The println statements that I added were called. But deinit did not execute, and reference3 not nil .

The next step is to move away from the method. When we exit the method, the variables go out of scope and are called by deinit :

enter image description here

+6
source

It is freed up because the compiler can recognize that the locally created object is no longer used. For example, in the code below, after the viewDidLoad method is viewDidLoad the Person method will be released, because there is no one to use the human object in the future.

 override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib.\ var reference1: Person? var reference2: Person? var reference3: Person? reference1 = Person(name: "John Appleseed") // prints "John Appleseed is being initialized reference2 = reference1 reference3 = reference1 reference1 = nil reference2 = nil // println(reference3?.name) } 

If you want to save the object, you need to create reference3 as property , as shown below:

 class ViewController: UIViewController { var reference3 : Person? override func viewDidLoad() { super.viewDidLoad() var reference1: Person? var reference2: Person? reference1 = Person(name: "John Appleseed") // prints "John Appleseed is being initialized reference2 = reference1 reference3 = reference1 reference1 = nil reference2 = nil // println(reference3?.name) } override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) println(reference3?.name) } } 
+1
source

Source: https://habr.com/ru/post/987924/


All Articles