如何正确删除Timer实例

时间:2017-06-05 09:44:36

标签: ios swift timer

我在我的项目中使用Select * from complaints where Code in ( 'LG/17/05/0','LG/17/05/2','LG/17/05/3','Local Council Board/17/05/1','Local Council Board/17/05/10','Local Council Board/17/05/11' ) 实例。

我创建了一个实例并将其添加到Timer

RunLoop

现在我在考虑如何正确停止和删除Timer:

  1. 我应该信任ARC并且不关心它吗?
  2. 可能需要timer = Timer(timeInterval: 0.1, repeats: true, block: { (timer) in print("Hello") }) if let timer = timer { RunLoop.current.add(timer, forMode: .commonModes) } 实施。如果是真的,那里面应该是什么

    deinit
  3. deinit { longPressTimer?.invalidate() longPressTimer = nil } 是不是很好? invalidate

    我已经从Stack中读过关于它的serval线程但是答案是矛盾的。有人能告诉我哪种方式是正确的并解释我为什么?

3 个答案:

答案 0 :(得分:2)

您需要 invalidate() = nil 与其他对象不同,定时器在保留计数达到零时不会被释放,除非它被停止(无效)。

假设您有一个当前有效的重复计时器。当你设置timer = nil时,它仍会在内存中持续存在并继续触发动作(可能iOS有一些机制可以让它保持活动状态,只要它仍处于活动状态)。所以经验法则是:当你想要摆脱它时,总是调用invalidate()并将计时器设置为nil。

答案 1 :(得分:0)

如果计时器重复,只要它的目标位于内存中,它就不会失效。

对我来说最好的解决方案是使用这个类 - 它将观察目标,并且目标是解除分配,它将使自身无效。

final class WeakTimer {
    private weak var timer: Timer?
    private weak var target: AnyObject?
    private let action: (Timer) -> Void

    private init(timeInterval: TimeInterval,
                     target: AnyObject,
                     repeats: Bool,
                     userInfo: Any?,
                     action: @escaping (Timer) -> Void) {
        self.target = target
        self.action = action
        self.timer = Timer.scheduledTimer(timeInterval: timeInterval, target: self, selector: #selector(fire(timer:)), userInfo: userInfo, repeats: repeats)
        RunLoop.main.add(self.timer!, forMode: .commonModes)
    }

    class func scheduledTimer(timeInterval: TimeInterval,
                              target: AnyObject,
                              userInfo: Any?,
                              repeats: Bool,
                              action: @escaping (Timer) -> Void) -> Timer {
        return WeakTimer(timeInterval: timeInterval,
                         target: target,
                         repeats: repeats,
                         userInfo: userInfo,
                         action: action).timer!
    }

    @objc fileprivate func fire(timer: Timer) {
        if target != nil {
            action(timer)
        } else {
            timer.invalidate()
        }
    }
}

答案 2 :(得分:0)

首先检查计时器是否存在?如果是,则将其视为无效

 if timer!= nil {
    timer.invalidate()
 }

请记住,如果您在任何VC中使用计时器,则在离开该VC时会使其无效(View Controller)