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?
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?
Rob
On
You asked:
When is
deinitcalled?
In short, for reference types, an object is deinitialized when the last strong reference is removed.
So, it is often not a question of any particular variable, but rather a question of all of the references, and it is deinitialized when the last strong reference is removed, right before it is deallocated. See The Swift Programming Language, Deinitialization and Automatic Reference Counting.
You then asked:
Or is Swift using Garbage-Collector?
Swift does not use garbage collection. There used to be garbage collection (back in the early Objective-C days, for macOS targets), but that has long been deprecated and was replaced with a reference counting system, later simplified with the introduction of ARC (automatic reference counting). But Swift has never implemented garbage collection.
The
deinitis intended to release resources (such as freeing memory that is not under ARC).(Thanks to Martin and Rob's input, we can conclude below)
When is
deinitcalled?Usually, when last strong-reference gets out of scope,
deinitis called instantly (then deallocation happens).But:
autoreleasefeature (which has conditions),deinitis called significantly later, long after last reference gets out of scope (whenautoreleasepool is drained).deinitis guaranteed to never get called !! (ifdeinitwas not already called).deinitis 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:Note that
deinitmay be skipped if relatedinitthrows at the right/wrong moment, see: https://forums.swift.org/t/deinit-and-throwing-initializers/38871Is it like
C++destructor?There is no equivalent of a
C++destructor inObjCorSwift.(
Objective-C++object's destructor (dealloc) are called during program termination, because that is required byC++spec, but that's all and else Obj-C++'sdeallocbehavior is almost same asdeinit.)Is Swift using Garbage-Collector?
No, but whenever
autoreleasefeature affects objects, thedeinitcan be postponed (till autorelease-pool is drained, as mentioned above).