Memory Leaks in the Swift Playground/Deinit{} Not Called Consistently

Deinit method is never called - Swift playground

Xcode's Playgrounds for Swift don't work like regular apps; they aren't being run just once. The objects created stay in memory and can be inspected until you change the code, at which point the whole playground is reevaluated. When this happens, all previous results are discarded and while all object will be deallocated, you won't see any output from that.

Your code is correct, but Playgrounds is not suited to test things related to memory management.

Here's a related SO question: Memory leaks in the swift playground / deinit{} not called consistently

deinit not called in specific case

I expect deinit to be called at program termination

You should not expect that. Objects that exist at program termination are generally not deallocated. Memory cleanup is left to the operating system (which frees all of the program's memory). This is a long-existing optimization in Cocoa to speed up program termination.

deinit is intended only to release resources (such as freeing memory that is not under ARC). There is no equivalent of a C++ destructor in ObjC or Swift. (C++ and Objective-C++ objects are destroyed during program termination, since this is required by spec.)

swift deinit method not working when UIView is removed from memory

Parent ViewController can hold you UIView. You have to set to nil a property, that stored you UIView in parent UIViewController for release uiview.

Or override removeFromSuperview() and place your deinit code in it.

Swift and RAII: deinit behavior inconsistent between project and playground

Playgrounds are compiled differently – unlike a regular compile, the compiler transforms your code by inserting various calls to instrumentation. This lets you, for example, see what expressions evaluate to. However it can have the unfortunate side-effect of changing how your program behaves.

It's worth noting however that unlike languages like C and C++, Swift doesn't guarantee that local variables (or in your case, values from unused expressions) will remain valid until the end of the scope in which they're defined. The optimiser is free to deinitialise them earlier.

If you want to guarantee the lifetime of SomeClass in your example, you can use withExtendedLifetime:

func test() {
withExtendedLifetime(TestClass()) {
defer { print("defer") }
print("end of scope")
}
}

Is deinit called when init throws an exception?

deinit is not called on instances that have not been correctly initialized.

If init fails for some reason, then the class instance never starts existing. Therefore, there is no instance on which deinit could be called.

If deinit could be called on a partially initialized instance, it would break the contract of non-optional properties - in your example the socket property would not get assigned and it would still be accessible in deinit as a non-optional but without a value.

How to print to console using a Swift playground?

This happens because Xcode 6 is in beta. Various things within the playground fail intermittently, there is nothing wrong with your code.

When are objects that hold unowned references deallocated?

Your code will most likely only work in the playground, where the memory management is a little... fuzzy.

When I ran this in Xcode, it crashes as you'd expect. The playground is meant to make it easy to test the syntax, play with some classes, etc. It's not the best place to play around with weak/unretained variables.

I haven't found any documented sources describing how exactly the memory is managed in a playground, but it's definitely different from how it will be in an actual runtime.



Related Topics



Leave a reply



Submit