3

Following this question, and more specifically, this comment:

because retain (aka strong reference) cycles in the common case where the timer's target is also its owner

I am wondering why dealloc isn't a good place to invalidate an NSTimer.

I remember profiling my app without auto-repeating NSTimer invalidation and then with invalidation in dealloc, and the memory correctly freed.

Is dealloc working differently in the latest iOS?

Isn't in fact your overridden dealloc called prior to any NSObject deallocation? What is dealloc even used for, then? If not manually deallocating the respective object's properties?

Community
  • 1
  • 1
Iulian Onofrei
  • 9,188
  • 10
  • 67
  • 113
  • 3
    NSTimer is Retaining your object, because of this reason, Dealloc will never be called ( thus NSTimer invalidated ) – ogres Nov 01 '16 at 11:14
  • the `-dealloc` method is being invoked by the system _when_ the system wants to deallocate a released object, you cannot rely on _when_ that actually happens while the timer is still running; on the other hand you can could make accidentally a strong retain cycle when the `-dealloc` will never be triggered, and your timer would be also stuck in background doing a task which you don't need to anymore, which may lead inconsistent behaviour or even crash, but definitely makes your app a bad memory citizen. – holex Nov 01 '16 at 11:15
  • Isn't `UIViewController`'s `dealloc` called after you call `dismissViewController:animated:`? – Iulian Onofrei Nov 01 '16 at 11:19
  • 1
    no, dealloc is called after its not retained ( pointed ) anywhere else – ogres Nov 01 '16 at 11:35
  • I will run some Profiling again and try to understand what was happening. – Iulian Onofrei Nov 01 '16 at 19:04
  • Indeed, this is correct, as [this page](http://www.cocoabuilder.com/archive/cocoa/311831-arc-and-dealloc.html) says it too. @ogres, Care to post an answer to accept it as solution? – Iulian Onofrei Nov 02 '16 at 15:11

1 Answers1

1

ARC will only release ( and call dealloc ) objects, when there are no strong references pointing to this object ( no one is retaining ).

NSTimer creates strong reference and it will retain target.

This means, dealloc will not be called, because NSTimer still has strong reference to the object. If there is no dealloc, this means NSTimer will never be invalidated ... leads to memory leak or even crashes.

There is a way to invalidate timer in dealloc or when target becomes nil. Have a look at the answer here.

Community
  • 1
  • 1
ogres
  • 3,660
  • 1
  • 17
  • 16