我如何在不在ViewWillDisAppear中进行nstimer无效/降低nstimer


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 selfunowned self来防止自己保留,因此您可以在deinit中无效。这就是为什么我创建了一个基于GCD的计时器类,以替代NSTIMER。

我知道为时已晚,但是您可以在viewWillDissappear中将其无效;

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    if isMovingFromParentViewController() {
        yourTimer.invalidate()
    }
}

如果 isMovingFromParentViewController返回true,则意味着用户点击返回按钮和pop到导航堆栈中的最后视图控制器。因此,deinit将在真实的位置调用。

最新更新