ARC deinit time question

Yes, deinit will be printed before bar independent of optimization.

Although this isn't formally specified by the language, the optimizer should not reorder print statements in deinitializers with print statements in regular code in either direction. We can say the same about any call to a function outside of Swift that the optimizer can't reason about. The compiler provides this guarantee today, and I don't foresee any need to change it.

Important caveats:

Deinitializers are unordered relative to each other

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

func foo() {
  let a = A()
  let b = B()
  print("foo")
}

Both these outputs are valid:

foo
deinit B
deinit A

or

foo
deinit A
deinit B

Eagerly consumed variables

Variables can declare that they are "eagerly consumed" as an optimization. These variables may be destroyed after their last use. Deinintialization still won't be delayed past an external call, so this doesn't apply to your example.

Some types declare this as their default behavior. Notably, all the standard library collections and Strings are eagerly consumed. (This is currently spelled @_eagerMove). They are optimizable as-if their deinitialization doesn't have side effects.

In the near future, we plan to support and consuming parameter and variable declarations, which may be destroyed immediately after their last use.

1 Like