When is deinit
exactly called?
Is it like C++
guaranteed to be called when last reference gets out of scope (by return, throw or exit)?
Or is Swift
using Garbage-Collector?
The deinit
is intended to release resources (such as freeing memory that is not under ARC).
(Thanks to Martin and Rob's input, we can conclude below)
deinit
called?Usually, when last strong-reference gets out of scope,
deinit
is called instantly (then deallocation happens).
But:
autorelease
feature (which has conditions), deinit
is called significantly later,
long after last reference gets out of scope (when autorelease
pool is drained).deinit
is guaranteed to never get called !!
(if deinit
was not already called).deinit
is called before strong-ref-variable's scope ends:
In Swift unlike other languages, when we set a weak-reference equal to a strong-reference,
it could result to nil
(which is absolutely allowed by Swift).
This happens if compiler detects that the remaining lines of scope, have NOT any strong-reference.
Possible workaround is using withExtendedLifetime(_:_:)
global-method / function, like:
withExtendedLifetime(myStrongRefVariable) {
// Do something that only needs a non-nil weak reference.
}
Note that deinit
may be skipped if related init
throws at the right/wrong moment, see:
https://forums.swift.org/t/deinit-and-throwing-initializers/38871
C++
destructor?There is no equivalent of a C++
destructor in ObjC
or Swift
.
(Objective-C++
object's destructor (dealloc
) are called during program termination,
because that is required by C++
spec,
but that's all and else Obj-C++'s dealloc
behavior is almost same as deinit
.)
No, but whenever autorelease
feature affects objects,
the deinit
can be postponed (till autorelease-pool is drained, as mentioned above).