【问题标题】:Using NSTimer is Swift causes 'deinit' not to call使用 NSTimer 是 Swift 导致 'deinit' 不调用
【发布时间】:2015-08-25 18:20:37
【问题描述】:

使用 NSTimer 后,类 deinit 方法永远不会被调用。 该类是用 Swift 编写的,我在“init”处调用计时器,如下所示:

init(eventsDistributor : EventsDistributor, orderSide : ORDER_SIDE, stockViewModel : StockViewModel, orderType : ORDER_TYPE_ENUM, orderPrice : NSNumber) {
    self.eventsDistributor = eventsDistributor
    self.orderSide = orderSide
    self.stockViewModel = stockViewModel
    self.orderType = orderType
    self.orderPrice = orderPrice
    super.init()
    _events()
    loadPreOrderDetails()

    //Here I call the Timer:
    var reloadTimer = NSTimer.scheduledTimerWithTimeInterval(10.0, target: self, selector: "loadSecurityTradeInfo", userInfo: nil, repeats: true)
    reloadTimer.fire()        
}

我也尝试使用NSTimer 作为局部变量,但没有成功... 有人遇到这个问题吗?我可以在 Swift 中使用不会导致类不被释放的计时器吗?谢谢

【问题讨论】:

标签: swift nstimer deinit


【解决方案1】:

NSTimer 保留它的目标。没有惊喜。你需要先让定时器失效

【讨论】:

  • 对此的快速跟进问题 - 假设提供了一个供公众使用的类,如果用户可以实例化该类并在完成后简单地将引用设置为 nil,那就太好了。问题是,在用户取消对象之前,我不知道何时使我的计时器无效。那么我是否只需要要求我的班级的用户在我的班级上调用某种“endSession”方法,这样我就有机会使私有计时器无效?有没有更优雅的方法来做到这一点?我问是因为我班级的任何用户忘记调用 end 方法都会导致内存泄漏!
  • 除了“调用某种 'endSession' 方法”之外我什么都想不出来
【解决方案2】:

计时器对其目标(自身)具有强引用。并且目标被安排到运行循环,它持有对它的强引用,直到计时器失效。在您使计时器无效(reloadTimer.invalidate,或者可能来自 loadSecurityTradeInfo 方法)之前,该对象不会消失。

这实际上非常好,因为在对象消失后,向对象发送 loadSecurityTradeInfo 消息的计时器将是一个非常非常糟糕的主意。

loadSecurityTradeInfo 可能应该更改为将计时器作为参数的方法,这样它就可以使其无效。

【讨论】:

  • 感谢您的快速响应,只要用户在将此当前类作为变量保存的 MasterController 中,计时器就需要每 10 秒运行一次。所以你说唯一的方法是当masterViewController不再出现时手动调用计时器上的“Invalidate”?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-21
  • 2019-09-26
  • 1970-01-01
  • 1970-01-01
  • 2015-11-24
  • 2023-03-11
相关资源
最近更新 更多