为什么关闭视图控制器不会从内存中清除呈现的控制器?
Why dismissing view controller is not clearing presented controller from memory?
我有2个控制器。他们每个人在屏幕上只有一个按钮。对于第一个控制器按钮是模态呈现第二个控制器,对于第二个控制器按钮是解散呈现的控制器。
第一个密码简单如门:
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)
}
}
}
第二个控制器代码包含一些额外的代码,用于检测在关闭控制器后仍然存在。
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)")
}
第二个控制器的所有代码如下:
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)
}
}
}
因此,当您第一次 运行 在第一个控制器屏幕上按下按钮时,您将每隔 5 秒在控制台中看到如下内容:
Class Proj.WebViewController 索引为 0
但是如果您关闭控制器并再次出现,那么您将同时看到:
Class Proj.WebViewController 索引为 0
Class Proj.WebViewController 索引为 1
据我所知,解散并不是从内存中删除呈现的控制器,即使没有人从我身边抓住他。
有人知道这是什么吗?我该如何解决?
您也可以下载sample project
计时器正在捕获您的视图控制器
你应该保留一个weak reference到计时器,并在dismissSelf
[=中添加timer.invalidate()
13=]
在 swift 中,如果您的对象被利用,那么编译器会理解它会被使用,所以即使您 dismissViewControllerAnimated
UIViewController
。它不会是 dealloc
。所以你需要在 dismissViewControllerAnimated
触发之前 invalidate()
计时器。这里 dealloc
被替换为 deinit
。
@IBAction func dismissSelf() {
timer.invalidate()
self.dismissViewControllerAnimated(true, completion: nil)
}
deinit {
self.view.removeFromSuperview()
println("call")
// perform the deinitialization
}
希望对您有所帮助。
阅读更多
swift-nstimer-tutorial-lets-create-a-counter-application
&simple-stopwatch-app-in-swift
使用这个...
@IBAction func dismissSelf() {
if let presentingController = self.presentingViewController {
timer.invalidate()// add this
presentingController.dismissViewControllerAnimated(true, completion: nil)
}
}
我也遇到过这种情况 "Why dismissing view controller is not clearing presented controller from memory?"。所以就我而言,我有
FirstViewController: UIViewController {
var secondViewController: SecondViewController
override func viewDidLoad() {
super.viewDidLoad()
//Important...Don't Do instantiation here....
//Instantiate only when it's going to be used
secondViewController = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SecondViewController") as? SecondViewController
}
@IBAction fun buttonAction() {
self.present(secondViewController, animated: true)
}
}
The Above Code didn't called deinit on my SecondViewController
对我有用的修复:
FirstViewController: UIViewController {
var secondViewController: SecondViewController
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction fun buttonAction() {
//Do the instantiation here
secondViewController = UIStoryboard.init(name: "Main", bundle: nil)
.instantiateViewController(withIdentifier: "SecondViewController") as? SecondViewController
self.present(secondViewController, animated: true)
//setting the view controller reference variable to nil
self.secondViewController = nil
}
}
SecondViewController 的引用保留在 SecondViewController 变量上,直到它被重新初始化或设置为 nil。
我有2个控制器。他们每个人在屏幕上只有一个按钮。对于第一个控制器按钮是模态呈现第二个控制器,对于第二个控制器按钮是解散呈现的控制器。
第一个密码简单如门:
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)
}
}
}
第二个控制器代码包含一些额外的代码,用于检测在关闭控制器后仍然存在。
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)")
}
第二个控制器的所有代码如下:
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)
}
}
}
因此,当您第一次 运行 在第一个控制器屏幕上按下按钮时,您将每隔 5 秒在控制台中看到如下内容:
Class Proj.WebViewController 索引为 0
但是如果您关闭控制器并再次出现,那么您将同时看到:
Class Proj.WebViewController 索引为 0
Class Proj.WebViewController 索引为 1
据我所知,解散并不是从内存中删除呈现的控制器,即使没有人从我身边抓住他。
有人知道这是什么吗?我该如何解决?
您也可以下载sample project
计时器正在捕获您的视图控制器
你应该保留一个weak reference到计时器,并在dismissSelf
[=中添加timer.invalidate()
13=]
在 swift 中,如果您的对象被利用,那么编译器会理解它会被使用,所以即使您 dismissViewControllerAnimated
UIViewController
。它不会是 dealloc
。所以你需要在 dismissViewControllerAnimated
触发之前 invalidate()
计时器。这里 dealloc
被替换为 deinit
。
@IBAction func dismissSelf() {
timer.invalidate()
self.dismissViewControllerAnimated(true, completion: nil)
}
deinit {
self.view.removeFromSuperview()
println("call")
// perform the deinitialization
}
希望对您有所帮助。
阅读更多
swift-nstimer-tutorial-lets-create-a-counter-application &simple-stopwatch-app-in-swift
使用这个...
@IBAction func dismissSelf() {
if let presentingController = self.presentingViewController {
timer.invalidate()// add this
presentingController.dismissViewControllerAnimated(true, completion: nil)
}
}
我也遇到过这种情况 "Why dismissing view controller is not clearing presented controller from memory?"。所以就我而言,我有
FirstViewController: UIViewController {
var secondViewController: SecondViewController
override func viewDidLoad() {
super.viewDidLoad()
//Important...Don't Do instantiation here....
//Instantiate only when it's going to be used
secondViewController = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SecondViewController") as? SecondViewController
}
@IBAction fun buttonAction() {
self.present(secondViewController, animated: true)
}
}
The Above Code didn't called deinit on my SecondViewController
对我有用的修复:
FirstViewController: UIViewController {
var secondViewController: SecondViewController
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction fun buttonAction() {
//Do the instantiation here
secondViewController = UIStoryboard.init(name: "Main", bundle: nil)
.instantiateViewController(withIdentifier: "SecondViewController") as? SecondViewController
self.present(secondViewController, animated: true)
//setting the view controller reference variable to nil
self.secondViewController = nil
}
}
SecondViewController 的引用保留在 SecondViewController 变量上,直到它被重新初始化或设置为 nil。