ios - NSTimer crashing after app returns to foreground -


this bug has been in code days - i've been trying solve no avail. i've done extensive debugging, on simulator , on device, logging, crashlytics throwing crash log, , has nstimer being sent message after deallocation. i'll explain further.

this nstimer controls uitoolbar label on view controllers, , keeps updating label show relative time when user refreshed uitableview. upon load, , every refresh, shows updated now , if user doesn't refresh/go vc, keeps updating every 60 seconds. so, after minute, show updated 1 minute ago. nstimer triggers method uilabel updating. on user refresh (by pulling on refresh control), method invoked manually inside getallitems (that's why pass nil).

my nstimer defined in superclass as:

@property (nonatomic, weak) nstimer *updatedatetimer; 

this code items tableview:

- (void)getallitems {     kill_timer(self.updatedatetimer);     self.updatelabel = [formatters boldlabelwithlabel:self.updatelabel                                              withtext:@"checking items..."                                              withfont:[uifont fontwithname:kopensansbold size:15.0f]];      dispatch_async(dispatch_get_global_queue(dispatch_queue_priority_default, 0), ^{         [self fetchobjectswithrequest:self.request];         sleep(1);         dispatch_async(dispatch_get_main_queue(), ^{                 [self.refreshcontrol performselector:@selector(endrefreshing) withobject:nil afterdelay:0];              self.updateddate = [nsdate date];             [self updatetimer:nil];             self.updatedatetimer = [nstimer scheduledtimerwithtimeinterval:ktoolbarupdatelabelinterval                                                                     target:self                                                                   selector:@selector(updatetimer:)                                                                   userinfo:nil repeats:yes];         });     }); } 

and kill_timer(q) defined, in superclass, as:

#define kill_timer(q) if (q) {ddlogverbose(@"killing timer: %@", q); [q invalidate]; q=nil;} 

this define invoked in 2 methods:

a) in getallitems method: when (re)load items (by invoking method in viewdidload or user refreshing table view), try kill current timer that's active, show 'checking items', fetch items, show 'updated now' , schedule timer execute every 60 seconds.

b) on each viewwilldisappear`, such:

- (void)viewwilldisappear:(bool)animated {     [super viewwilldisappear:animated];     kill_timer(self.updatedatetimer); } 

however, if hit home button, , reopen app, (not always, if had switched view controllers) crashes following message (with nszombies enabled):

2013-07-11 17:21:37.576 app[3923:907] *** -[itemcdtvc setupdatedatetimer:]: message sent deallocated instance 0x20bc49f0 

i have nsnotification invokes getallitems:

// notification received when user returns app (refreshes table view) [[nsnotificationcenter defaultcenter] addobserver:self selector:@selector(getallitems) name:uiapplicationwillenterforegroundnotification object:nil]; 

this happens after switch view controllers using menu, leave app, , reopen (the app not terminate). it not crash if user stays in app, regardless of how many view controllers switch between.

it's pretty annoying bug, because although it's reproduce, don't know how fix it. appreciated.

you should invalidating timers when app becomes inactive. -applicationwillresignactive: place that. can create new timers when app becomes active again.

an educated guess app crashing because timers killed automatically when app goes inactive, , crash when app returns foreground , tries access timers, no longer valid.


Comments