var faderTimer: NSTimer?
override func viewDidLoad() {
super.viewDidLoad()
self.faderTimer = NSTimer.scheduledTimerWithTimeInterval(self.fadeTime, target: self, selector: Selector("fadeBackground"), userInfo: nil, repeats: true)
}
我需要在控制器deinits之前使该计时器无效。
deinit {
//never gets called
if let timer = self.faderTimer {
self.faderTimer!.invalidate()
self.faderTimer = nil
}
}
但是,我不能将其粘在deinit()中。看来我必须在viewWillDisappear
中使其无效。但是,我不想这样做,因为它弄乱了背景切换。(从背景返回不会调用ViewWillAppear,因此我必须使用通知开始计时器,这是一个巨大的痛苦。)我宁愿在viewDidload上启动计时器并在Deinit()上停止它。
我宁愿在
上停止它viewDidLoad
上启动计时器,然后在deinit()
好吧,你不能。计时器正在保留您(self
),并将继续这样做,直到无效为止。这意味着,除非您采取行动使计时器在其他地方无效,否则deinit
将永远不会被称为,并且视图控制器将泄漏(它永远不会消失,并且它所保留的所有内存,以及在其所有属性中,将继续举行)。您必须找到另一个地方使计时器无效;就是这样。
如果您不喜欢,则不要使用nstimer 。改用GCD和dispatch_source_t
。这具有一个优势:它基于块(闭合) - 您可以在块内使用weak self
或unowned self
来防止自己保留,因此您可以在deinit
中无效。这就是为什么我创建了一个基于GCD的计时器类,以替代NSTIMER。
我知道为时已晚,但是您可以在viewWillDissappear
中将其无效;
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
if isMovingFromParentViewController() {
yourTimer.invalidate()
}
}
如果 isMovingFromParentViewController
返回true,则意味着用户点击返回按钮和pop到导航堆栈中的最后视图控制器。因此,deinit
将在真实的位置调用。