如果不在viewWillDisappear中执行此操作,我如何使NSTimer无效/取消?

时间:2015-05-04 03:46:16

标签: ios swift oop

var faderTimer: NSTimer?
override func viewDidLoad() {
    super.viewDidLoad()

    self.faderTimer = NSTimer.scheduledTimerWithTimeInterval(self.fadeTime, target: self, selector: Selector("fadeBackground"), userInfo: nil, repeats: true)
}

我需要在控制器取消之前使此计时器无效。

deinit {
    //never gets called
    if let timer = self.faderTimer {
        self.faderTimer!.invalidate()
        self.faderTimer = nil
    }
}

但是,我不能把它粘在deinit()中。似乎我必须在viewWillDisappear中使其无效。但是,我不想这样做,因为它会影响背景切换。 (从后台返回不会调用viewWillAppear,所以我必须使用通知来启动计时器,这是一个巨大的痛苦。)我宁愿在viewDidLoad上启动计时器并在deinit()上停止它。

2 个答案:

答案 0 :(得分:6)

  

我只是在viewDidLoad启动计时器并在deinit()

上停止计时器
嗯,你不能。计时器保留您(self),并将继续这样做,直到它失效。这意味着除非您采取措施使其他地方的计时器无效,否则deinit将永远不会被称为并且视图控制器将泄漏(它将永远不会存在,并且它将是所有内存将继续举行,以及所有财产的持有)。你必须找到另一个地方来使计时器无效;这就是它的方式。

如果您不喜欢,则不要使用NSTimer 。请改用GCD和dispatch_source_t。这样做的好处是它基于一个块(一个闭包) - 你可以在块内部使用weak selfunowned self来防止自己被保留,因此你可以在{ {1}}如果你愿意的话。这正是我创建GCD-based timer class作为NSTimer的替代品的原因。

答案 1 :(得分:3)

我知道现在为时已晚,但你可以像viewWillDissappear那样无效;

override func viewWillDisappear(animated: Bool) {

    super.viewWillDisappear(animated)

    if isMovingFromParentViewController() {
        yourTimer.invalidate()
    }
}

如果isMovingFromParentViewController返回true,则表示用户点击后退按钮并弹出导航堆栈中的最后一个视图控制器。因此,deinit将在真实位置被调用。