Python doesn't guarantee this behaviour
https://docs.python.org/2/reference/datamodel.html#object.del
It is not guaranteed that
__del__()
methods are called for objects that still exist when the interpreter exits.
Python doesn't guarantee this behaviour
https://docs.python.org/2/reference/datamodel.html#object.del
It is not guaranteed that
__del__()
methods are called for objects that still exist when the interpreter exits.
The Swift runtime can only guarantee that objects which it deallocates have their deinit
method called. When the OS is reclaiming memory, it doesn't matter if this is because of a crash or a normal exit. Either way, it's not the runtime in charge anymore, so no Swift language guarantees are in effect.
Yes, the runtime could delay a normal exit until all (global) objects are properly deallocated, but it makes no promise to do so.
Does it say so? This is not an issue of: we don't do it cause we don't say it and people don't expect it. The runtime should deallocate all the objects before finish, otherwise, it should say so, explicitly. In the end, the runtime is creating a main
function and returning a value to the OS anyway, so, the fact that it doesn't deallocate the objects in the global scope is just laziness.
To quote Larry Wall: laziness is a virtue.
I don't think this thread is going anywhere. You have an expectation, based on a simple Python example. Pretty much every language, including Python, violates this expectation.
It could, though.
For example, I could imagine that Swift scripts would want to make sure deinitializers run, to, say, delete some temp file.
I mean that saying "you can't rely on deinitializers" is a good thing, but saying HOW to make deinitializers run reliably is even better.
For example, do we have the absolute guarantee that a local variable in a function is deinitialized?
#!swift
class TempFile { ... }
// No deinit guarantee
let t = TempFile()
func main() {
// deinit guarantee?
let t = TempFile()
}
main()
The answer to the question as written is ânoâ. Swift cannot guarantee this because you can escape references to these objects nearly anywhere.
There is no general question you can ask about reference counted objects in Swift that can be answered with âthe deinitializer is definitely called hereâ. Whether a deinitializer is called is dependent on the entire history of the program execution, as well as the exact behaviour of the program in question. You can ask that of specific code samples, where the answer can be drawn from the semantics of the language as best as possible.
But as you note, Swiftâs guidance on deinit is the same as Python and Java: in general, you shouldnât rely on deinit to clean your resources up. If you need deterministic cleanup, you should write a with
-style function that will do that cleanup.
It might, and it should.
Created by the language. As you saw in a previous reply about Python, they make it clear you can't rely on destructors when the interpreter exists. Swift documentation on the other hand says nothing about it.
So, there is at the very least two places where this could go:
Where does it says this? I've looked for it and didn't find it.
What's "it"? Swift doesn't have a language specification. There is no concrete reference on when deinitializers run. I appreciate that I wasn't clear there: by "Swift's guidance" I mean "the guidance of the Swift community", just as I meant with the Python and Java examples.
"It" being the guidance, yes. I went through the documentation (basically this), and found nothing like that.
Relying on the community is not a very good idea, since the community does, inherently, have different views on what's expected and what's correct.
I see your point tho. Thanks
If you have a static property in a Swift file I donât think it gets deinit
ed on process exit, either. Or if you have any kind of top-level object that contains children objects theyâre not going to get automatically deinit
ed. Youâd have to do a bunch of work to keep track of all top-level objects (how do you even distinguish them?).
One might argue itâd be nice to know that deinit
will always be called for everything that was init
ed, but thatâd be an enormous runtime burden and isnât how the system around Swift works. Cocoa processes can be killed at any timeÂč by the system, in general. This is a good thing â it makes the system much snappier for the user.
Also, as has been pointed out several times, processes go away for other reasons that clean exits, so any, say, files you create need a better solution than trying to remove them in a deinit
call.
If you explicitly want to clean stuff up when you quit an app make your own little pool of things to clean â if youâre on Cocoa systems you can turn off sudden termination when you have anything in the pool waiting, and then flush out the pool in the notifications that the app will terminate.
-Wil
Âč Yes, the developer can permanently turn off sudden termination, but itâs bad practice.