Invalidate non-repeating NSTimer after fired?
NSTimer* myTimer = [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(wantsUpdate:) userInfo:nil repeats:NO] Sometime after it fires (and occasionally before), I call if ( myTimer ) { [myTimer invalidate]; [myTimer release]; myTimer = nil; } Should I really be doing: if ( myTimer ) { if ([myTimer isValid]) [myTimer invalidate]; [myTimer release]; myTimer = nil; } I am doing it the first way without trouble... At least I think it is ok. The docs say non-repeating timers are invalidated after they fire. Which way is better? Comments? ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Invalidate non-repeating NSTimer after fired?
You must use the 2nd way. If you don't you could get a memory exception if the timer has fired and, therefore, been invalidated. On Aug 3, 2012, at 4:19 PM, Trygve Inda wrote: NSTimer* myTimer = [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(wantsUpdate:) userInfo:nil repeats:NO] Sometime after it fires (and occasionally before), I call if ( myTimer ) { [myTimer invalidate]; [myTimer release]; myTimer = nil; } Should I really be doing: if ( myTimer ) { if ([myTimer isValid]) [myTimer invalidate]; [myTimer release]; myTimer = nil; } I am doing it the first way without trouble... At least I think it is ok. The docs say non-repeating timers are invalidated after they fire. Which way is better? Comments? ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/3tothe4th%40comcast.net This email sent to 3tothe...@comcast.net Charlie Dickman 3tothe...@comcast.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Invalidate non-repeating NSTimer after fired?
Not if you've retained the timer - and if you haven't, then you shouldn't release it. Conversely if you *have*, you should release and nil it when it fires. On Aug 3, 2012, at 2:10 PM, Charlie Dickman wrote: You must use the 2nd way. If you don't you could get a memory exception if the timer has fired and, therefore, been invalidated. On Aug 3, 2012, at 4:19 PM, Trygve Inda wrote: NSTimer* myTimer = [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(wantsUpdate:) userInfo:nil repeats:NO] Sometime after it fires (and occasionally before), I call if ( myTimer ) { [myTimer invalidate]; [myTimer release]; myTimer = nil; } Should I really be doing: if ( myTimer ) { if ([myTimer isValid]) [myTimer invalidate]; [myTimer release]; myTimer = nil; } I am doing it the first way without trouble... At least I think it is ok. The docs say non-repeating timers are invalidated after they fire. Which way is better? Comments? ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/3tothe4th%40comcast.net This email sent to 3tothe...@comcast.net Charlie Dickman 3tothe...@comcast.net ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/lrucker%40vmware.com This email sent to lruc...@vmware.com ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Invalidate non-repeating NSTimer after fired?
You must use the 2nd way. If you don't you could get a memory exception if the timer has fired and, therefore, been invalidated. On Aug 3, 2012, at 4:19 PM, Trygve Inda wrote: My code looks like this: -(void)awakeFromNib { [self setUpdateTimer:[NSTimer scheduledTimerWithTimeInterval:kSomeValue target:self selector:@selector(wantsUpdate:) userInfo:nil repeats:NO]]; } -(void)wantsUpdate:(NSTimer *)inTimer { // do stuff // conditionally do [self setUpdateTimer:[NSTimer scheduledTimerWithTimeInterval:kSomeValue target:self selector:@selector(wantsUpdate:) userInfo:nil repeats:NO]]; } -(void)setUpdateTimer:(NSTimer *)inTimer { if (updateTimer) [updateTimer invalidate]; [updateTimer release]; updateTimer = nil; } updateTimer = [inTimer retain]; } setUpdateTimer can be called in three different ways... A: From awakeFromNib where updateTimer is of course nil and the new timer gets retained. All is ok here. B: From wantsUpdate: In this case we are being called from within the method triggered by the timer and thus the code has not yet fallen back into the run loop so updateTimer is true and [updateTimer isValid] is YES, and once we fall back to the run loop the timer will be invalidated. C: From somewhere else in the program. In this case updateTimer is true, but [updateTimer isValid] is NO since the code has already fallen back into the run loop and invalidated the timer. It needs to work in all three case but I think B is the concern since if I change the code to: if ([updateTimer isValid]) [updateTimer invalidate]; Then it will be invalidated in case B (because the code has not fallen back to the run loop to invalidate it on its own). Not sure if I should be invalidating it after it has fired in this case...before the system does How best to handle all three cases elegantly? ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Invalidate non-repeating NSTimer after fired?
On Aug 3, 2012, at 14:37 , Trygve Inda cocoa...@xericdesign.com wrote: I think B is the concern since if I change the code to: if ([updateTimer isValid]) [updateTimer invalidate]; Then it will be invalidated in case B (because the code has not fallen back to the run loop to invalidate it on its own). Not sure if I should be invalidating it after it has fired in this case...before the system does I think you're over-thinking the problem here. There's no reason to think that 'invalidate' is fragile. If the timer's still scheduled to fire, 'invalidate' will prevent from ever firing, according to the class documentation. Otherwise it's harmless. You don't care (and the documentation tells you not to care) when it's actually removed from the run loop. All you care about is that it won't fire. -(void)setUpdateTimer:(NSTimer *)inTimer { if (updateTimer) [updateTimer invalidate]; [updateTimer release]; updateTimer = nil; } updateTimer = [inTimer retain]; } You don't even need to be this careful. This shorter implementation is guaranteed to be just as safe: -(void)setUpdateTimer:(NSTimer *)inTimer { [updateTimer invalidate]; [updateTimer release]; updateTimer = [inTimer retain]; } It's also preferable to release the expired timer earlier, in the case where a new timer isn't started right away: -(void)wantsUpdate:(NSTimer *)inTimer { [updateTimer release]; updateTimer = nil; // do stuff // conditionally do [self setUpdateTimer:[NSTimer scheduledTimerWithTimeInterval:kSomeValue target:self selector:@selector(wantsUpdate:) userInfo:nil repeats:NO]]; } How best to handle all three cases elegantly? Personally, I'd do it the neater but slightly redundant way: -(void)awakeFromNib { [self startUpdateTimer]; } -(void)wantsUpdate:(NSTimer *)inTimer { [self stopUpdateTimer]; // do stuff // conditionally do [self startUpdateTimer]; } -(void)stopUpdateTimer { [updateTimer invalidate]; [updateTimer release]; updateTimer = nil; } -(void)startUpdateTimer { [self stopUpdateTimer]; updateTimer = [[NSTimer scheduledTimerWithTimeInterval:kSomeValue target:self selector:@selector(wantsUpdate:) userInfo:nil repeats:NO] retain]; } ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com