Home:ALL Converter>Why dismissing view controller is not clearing presented controller from memory?

Why dismissing view controller is not clearing presented controller from memory?

Ask Time:2015-04-28T17:55:22         Author:Vasyl Khmil

Json Formatter

I have 2 controllers. Each of them have only one button on screen. For first controller button is presenting modally second controller, and for second controller button is dismissing presented controller.

Code of first one is simple as door:

class ViewController: UIViewController {
    @IBAction func present(sender: AnyObject) {
        let storyboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
        if let controller = storyboard.instantiateViewControllerWithIdentifier("web") as? UIViewController {
            controller.modalTransitionStyle = UIModalTransitionStyle.FlipHorizontal
            self.presentViewController(controller, animated: true, completion: nil)
        }
    }
}

Second controller code contain some extra code for detecting that after dismissing controller still exist.

static var index: Int = 0
var index: Int

required init(coder aDecoder: NSCoder) {
    self.index = WebViewController.index++
    super.init(coder: aDecoder)
    let timer = NSTimer.scheduledTimerWithTimeInterval(5, target: self, selector: "action", userInfo: nil, repeats: true)
}

func action() {
    NSLog("Class \(self.dynamicType) index is \(self.index)")
}

And all code of second controller looks like:

class WebViewController: UIViewController {
    static var index: Int = 0
    var index: Int

    required init(coder aDecoder: NSCoder) {
        self.index = WebViewController.index++
        super.init(coder: aDecoder)
        let timer = NSTimer.scheduledTimerWithTimeInterval(5, target: self, selector: "action", userInfo: nil, repeats: true)
    }

    func action() {
        NSLog("Class \(self.view) index is \(self.index)")
    }

    @IBAction func dismissSelf() {
        if let presentingController = self.presentingViewController {
            presentingController.dismissViewControllerAnimated(true, completion: nil)
        }
    }
}

So when you will run this and press button on first controller screen for first time, then each 5 seconds you will see in console something like:

Class Proj.WebViewController index is 0

But if you will dismiss controller and present is again, then you will see both:

Class Proj.WebViewController index is 0

Class Proj.WebViewController index is 1

As I understand dismissing is not removing from memory presented controller even if nobody is catching him from my side.

Do somebody know what is it and how can i solve it?

Also you can download sample project

Author:Vasyl Khmil,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/29916123/why-dismissing-view-controller-is-not-clearing-presented-controller-from-memory
DongXu :

the timer is catching your view controller\n\nyou should keep a weak reference to the timer, and add timer.invalidate() in dismissSelf\n\nhttps://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSTimer_Class/index.html#//apple_ref/occ/instm/NSTimer/invalidate",
2015-04-28T10:37:17
Jatin Patel - JP :

In swift, if your object is utilize then compiler understood that it will in used so even you dismissViewControllerAnimated the UIViewController. it wan't be dealloc. so you need to invalidate() timer before dismissViewControllerAnimated fired. and here dealloc is replace with deinit. \n\n@IBAction func dismissSelf() {\n timer.invalidate()\n self.dismissViewControllerAnimated(true, completion: nil)\n }\n\ndeinit {\n\n self.view.removeFromSuperview()\n println(\"call\")\n // perform the deinitialization\n }\n\n\nHope this help you.",
2015-04-28T10:52:46
Yuyutsu :

Read more \n\nswift-nstimer-tutorial-lets-create-a-counter-application\n& simple-stopwatch-app-in-swift\n\nNSTimer_Class\n\nUse this ...\n\n@IBAction func dismissSelf() {\n if let presentingController = self.presentingViewController {\n timer.invalidate()// add this\n presentingController.dismissViewControllerAnimated(true, completion: nil)\n }\n }\n",
2015-04-28T10:57:55
yy