我怎样才能无效/取消一个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 self
或unowned self
来防止自己被保留,因此如果你愿意的话可以使定时器无效。 这就是为什么我创build了一个基于GCD的计时器类 ,作为NSTimer的替代品。
我知道这已经太迟了,但是你可以在viewWillDissappear
中将它遗忘,就像那样;
override func viewWillDisappear(animated: Bool) { super.viewWillDisappear(animated) if isMovingFromParentViewController() { yourTimer.invalidate() } }
如果isMovingFromParentViewController
返回true,则表示用户点击button并popup到导航堆栈中的最后一个视图控制器。 所以, deinit
将被称为真正的地方。