1

After using NSTimer, the class deinit method is never called. The class is written in Swift, and I call the timer at the "init" like so:

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

I tried using the NSTimer as a local variable too, and no success there... Anyone facing this issue? Is there a timer I can use in Swift which will not causes the class not to be dealloced? Thanks

shim
  • 9,289
  • 12
  • 69
  • 108
MCMatan
  • 8,623
  • 6
  • 46
  • 85
  • 1
    Possible duplicate of http://stackoverflow.com/questions/30022298/how-can-i-invalidate-deinit-a-nstimer-without-doing-it-in-viewwilldisappear. – Martin R Jun 10 '15 at 13:17

2 Answers2

5

The timer has a strong reference to its target (self). And the target is scheduled to the run loop, which holds a strong reference to it until the timer is invalidated. Until you invalidate the timer (reloadTimer.invalidate, or probably from within the loadSecurityTradeInfo method), the object won't go away.

Which is actually very good, because the timer sending a loadSecurityTradeInfo message to the object would be a very, very bad idea after the object has gone.

loadSecurityTradeInfo should probably be changed to a method that takes a timer as an argument, so it can invalidate it.

gnasher729
  • 51,477
  • 5
  • 75
  • 98
  • Thanks for the quick response, The timer needs to run every 10 seconds as long as the user is in a MasterController that holds this current class as a variable. So your saying the only way is to manually call "Invalidate" on the timer when the masterViewController isn't presented any more? – MCMatan Jun 10 '15 at 13:18
2

NSTimer retains its target. No surprise. You need to invalidate the timer first

Andrey Chernukha
  • 21,488
  • 17
  • 97
  • 161
  • 1
    a quick follow up question on this - assuming one is providing a class for public use, it would be nice if the user could instantiate the class and simply set the reference to nil when done. Thing is, I won't know when to invalidate my timers before the user nils out the object. So do I simply have to require the user of my class call some kind of 'endSession' method on my class where I have the chance to invalidate the private timers? is there a more elegant way to do this? I ask because any user of my class that forgets to call the end method will end up with mem leaks! – Woodstock Oct 16 '16 at 15:15
  • I can't think of anything except "call some kind of 'endSession' method" – Andrey Chernukha Oct 17 '16 at 17:32