Why is deinit not called until UIView is added to parent again?
deinit
is called when no one is referencing the object. If you don't set tstview
to nil
, your MyViewController is still referencing it, thus deinit
won't be called. When you call addView
, the statement tstview = test
finally removes the last reference to the old view, thus triggering the deinitializer.
You can read more about the concept of deinitialization in the Swift documentation.
If you want to be notified as soon as the view is detached, override willMove(toSuperview:)
instead.
class TestView: UIView {
...
override func willMove(toSuperview newSuperview: UIView?) {
if newSuperview == nil {
print("removed from parent")
}
}
}
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.
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 special circumstance that involves NSHashTable
As usual, the problem is that you are trying to test this in a playground. Don't. Playgrounds are the work of the devil.
Test in an actual app project and you will see that deinit
is called.
Example (iOS, but the equivalent in macOS would do fine):
import UIKit
class TestClass:NSObject {
var s1 = NSHashTable<TestClass>(options: .weakMemory)
func doit(bla:TestClass) {
s1.add(bla)
bla.s1.add(self)
}
deinit {
print("Deinit")
}
}
class ViewController: UIViewController {
var t1:TestClass? = TestClass()
var t2:TestClass? = TestClass()
override func viewDidLoad() {
super.viewDidLoad()
t1?.doit(bla:t2!)
t1 = nil // --> "Deinit"
print(t2?.s1) // --> it's empty
}
}
ViewController passed as parameter is not being deinitialized (Swift)
Strong references to each other.
Try to change class A:
weak var workOn: ProblemView?
func passView(passedVC: ProblemView){
workOn = passedVC
// I noticed, if I declare a varible locally like var workOn2 = passedVC, my problem is solved -
// but I need the variable globally, because I don't want to pass it around within this class
}
func doSth(){
// here I interact with variables of the passed ViewController
}
Can I use didSet in deinit?
Let's put an answer here so we can close this off.
It seems that property observers apparently do not run during
deinit
. This seems parallel to the fact that property observers do not run duringinit
, but unlike the latter, the former doesn't seem to be clearly documented anywhere.You can work around this by semantic trickery, but don't! That seems like a bug (and I've filed it).
The original use case was not a very good one to begin with. Hiding invalidation of a timer in replacement sounds like a potential maintenance nightmare. Agreed that invalidation and replacement go together like ham and eggs, what I always do is write a method that invalidates and replaces, in that order, and funnel everything through that method. (This can be enforced if necessary, but I won't go into that.) That method can be called during
deinit
.
SUPPLEMENTARY NOTE: Watch out, when using a timer, for memory management issues! You can easily get yourself into a situation where deinit
is never called, because you're retaining the timer but the timer is retaining you. You will then fail to invalidate the timer and your entire view controller will leak. You don't complain about that in your question, but it's a related matter so I thought I'd better flag it.
Related Topics
How to Customize the Title/Subtitle Font in Callout from Mkannotationview or Just Hide Them
How to Convert an Anykeypath to a Writablekeypath
Why Specializing a Generic Function Explicitly Is Not Allowed
Swift Error with Generic Array
Swiftui Button Interact with Map
How to Set an Initial Value for @Nsmanaged Property Pfobject Subclass
Are Swift Constants Lazy by Default
Can a Condition Be Used to Determine the Type of a Generic
Add a Xib File to a Swift Package
Swift Combine: What Are Those Multicast Functions for and How to Use Them
Best Way to Avoid Capturing a Copy of the Value in Closure
How to Respond with an Image Using Vapor
How to Access a Custom Function from Any File in the Same Swift Project
Video Upload to Amazon S3 in Swift