我怎样才能无效/取消一个NSTimer而不做viewWillDisappear?

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()。

我宁愿在viewDidLoad上启动计时器,并在deinit()

那么,你不能。 定时器保留你( self ),并将继续这样做,直到它失效。 这意味着,除非你采取行动来使其他地方的计时器失效,否则deinit将永远不会被调用,并且视图控制器将会泄漏 (它永远不会失去存在,并且它所拥有的所有内存以及它的所有属性将会继续举行)。 你必须find另一个地方使计时器失效。 就是那样子。

如果你不喜欢, 那就不要使用NSTimer 。 改为使用GCD和dispatch_source_t 。 这样做的好处是它基于一个块(一个闭包) – 你可以在块内部使用weak selfunowned self来防止自己被保留,因此如果你愿意的话可以使定时器无效。 这就是为什么我创build了一个基于GCD的计时器类 ,作为NSTimer的替代品。

我知道这已经太迟了,但是你可以在viewWillDissappear中将它遗忘,就像那样;

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

如果isMovingFromParentViewController返回true,则表示用户点击button并popup到导航堆栈中的最后一个视图控制器。 所以, deinit将被称为真正的地方。