UISwitch not deallocating

This is a repost of my question before but because of too many edit’s and I’ve simplified my examples, I thought it would be more clear if I create a new question instead of re-edit the questions multiple times.

PROBLEM:
UISwitch object somehow doesn’t deallocate even when nothing has been done with it.

  • Why calloutAccessoryControlTapped is called for tap on annotation view also?
  • How to include assets / resources in a Swift Package Manager library?
  • How to activate action sheet buttons with swift?
  • Calling delegate function from AppDelegate not working
  • Why can we not cast to protocol types with associated types but achieve the same effect using generics?
  • Unwrap String and check emptiness in the same if statement

  • PROJECT:
    There are only two view controllers. VC1 and VC2. VC1 has one button to present VC2. VC2 contains one button to dismiss itself and a property of a custom UISwitch, UILabel and a UIStepper.

    VC1:

    class VC1: UIViewController {
    
        let button = UIButton()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            view.addSubview(button)
    
            button.addTarget(self, action: #selector(open), for: .touchUpInside)
    
            // Some auto layout (not relevant to the question)
        }
    
        func open() { present(VC2(), animated: true) }
    }
    

    VC2:

    class VC2: UIViewController {
    
        let button = UIButton()
    
        let shifty = CustomSwitch()    // Note: nothing has been done with this
        let labels = CustomLabels()
        let steppy = CustomSteppy()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            view.addSubview(button)
    
            button.addTarget(self, action: #selector(close), for: .touchUpInside)
    
            // Some auto layout (not relevant to the question)
        }
    
        func close() { dismiss(animated: true) }
    }
    

    SUBCLASSES:

    class CustomSwitch: UISwitch  { deinit { print("Switch has been deinitialized") } }
    class CustomLabels: UILabel   { deinit { print("Labels has been deinitialized") } }
    class CustomSteppy: UIStepper { deinit { print("Steppy has been deinitialized") } }
    

    The only reason I created these subclasses is so I could track them easier in the profiler. The same happens even when I don’t subclass UISwitch.

    EDIT:
    I’ve added a deinit to the subclasses and both the UILabel as well as the UIStepper are showing the message:

    Labels has been deinitialized
    Steppy has been deinitialized
    

    So it doesn’t seem the UISwitch is getting deinitialized.

    SCREENSHOT:
    In this screenshot, I’ve opened and closed VC2 multiple times. In there you can see only the object CustomSwitch has stayed persistent while CustomLabels and CustomSteppy has been deallocated just as it should be.

    Original state

    As suggested by Rmaddy and also the reason why I wanted to create a new question is the result of the reference counts. I’ve followed some explanations on SO but I’m not very sure what to make out of it entirely.

    Reference counts (collapsed)

    Reference counts


    QUESTION:
    Why is this UISwitch behaving like this and how can I fix this?

    Solutions Collect From Internet About “UISwitch not deallocating”

    This is (finally) fixed in iOS 10.2