1

I'm trying to understand how box allocated instance are retained. On the screen here, we

class A {
    deinit {
        print("deleted")
    }
}

var closure: (() -> Void)!

if true {
    var aa: A? = A()
    closure = {
        // Box wraps Optional<A> without creating new variable, it destroyed cuz it follows outer changes to variable
        print(aa)
    }

    aa = nil
}

closure() // output: deleted; nil

That's okey, this is what I expect expect, as i mentioned because -> Box wraps Optional<A> without creating new variable, it destroyed cuz it

Next example legit too:

class A {
    deinit {
        print("deleted")
    }
}

var closure: (() -> Void)!

if true {
    var aa: A? = A()
    closure = { [weak aa] in
        // creating a weak variable, that ends up when scope is over. That's okay
        print(aa)
    }

}

closure() // output: deleted; nil

But this example, get me confused a bit

class A {
    deinit {
        print("deleted")
    }
}

var closure: (() -> Void)!

if true {
    var aa: A? = A()
    closure = {
        // Box retains Optional<A> without creating new variable after if scope end, it doesn't destroyed? But why?
        print(aa)
    }
}

closure() // output: Optional(__lldb_expr_27.A)

Why in last example when scope is over, box allocated instance still gets retained? Is there some implicit copying when scope is over?

  • `aa` is captured by `closure`, which is still in scope. – jnpdx Jan 31 '22 at 07:04
  • Nah, scope is over, optional is value type, so capturing doesn't create new variable it put it on heap via box. I'm interested in how does box keeps instance alive after scope? – Pyrettt Pyrettt Jan 31 '22 at 07:10

1 Answers1

0

This is what I understand is happening.

When you do

var aa: A? = A()

Only self has a strong reference to aa so aa reference count is 1.

When you do

if true {
    var aa: A? = A()

    closure = {
        print(aa)
    }
}

Because closure requires aa, closure also has a strong reference to aa now so aa reference count is 2.

When you go out of scope, self no longer points to aa and its reference count decreases by 1 but aa cannot be deinitialized because its reference count is not 0 since closure strongly references it.

Closure strong weak ARC reference retain cycle swift

ARC retain cycle swift Closure strong weak reference

Shawn Frank
  • 4,381
  • 2
  • 19
  • 29