NSTimer invalidation - iphone

If I create a timer which never repeats
[NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:#selector(updateSystems) userInfo:nil repeats:NO];
do I still need to invalidate it?
Also, is releasing the instance one step in the invalidate method? Since I'm not using alloc my timer variable shouldn't have to be released, although when creating a timer it automatically should create a new thread? Does the timer still add up on the stack?
I need some clarity.
Thank you

See the documentation for the method. It says:
repeats
If YES, the timer will repeatedly reschedule itself until invalidated. If NO, the timer will be invalidated after it fires.

You are not creating any pointer to NSTimer. You are using it directly through a class method. This method does not creates a new instance of NSTimer so you don't have to release it.

Related

NSTimer speeds up after UI activity

I make an asynchronous http request using NSURLConnection every 11 seconds using a NSTimer.
The NSTimer runs on the main run loop. The request has a timeout of 10 seconds.
The NSTimer works well until I increase UI activity on the app (like tapping on UIButtons, dismissing UIAlertViews frequently).
After this the NSTimer speeds up and runs like a while loop without any delays. This creates a lot of problems in the app as I can't make proper handling of the connection responses.
The problem is that you are declaring an NSTimer inside your button action... now every time this button is pressed the NSTimer interval is compiled onto its previous interval and the result is that it gets called twice as often... the next time it's twice as often than the previous twice as often.... etc.
The best way to do it is define the NSTimer in the .h file and then every time you have code in your .m file to call it first check if it's already there and if so invalidate and release it.
if(myTimer){
[myTimer invalidate];
[myTimer release];
}
myTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(timeInterval) userInfo:nil repeats:YES];

NStimer issue in Cocoa-Touch

My application needs to show a temporary message, so I created Toast like android myself. It works well for only one toast. I am using NSTimer to hide the message. If I display more than one toast the timer becomes a problem. Only the last added toast becomes hidden, others do not become hidden. How can I hide all toasts?
Code:
Remove function:
-(void)removeToast
{
NSLog(#"removed");
[self.view removeFromSuperview];
}
Timer start:
timer = [NSTimer scheduledTimerWithTimeInterval:(4.0f)
target:self
selector:#selector(xxxx)
userInfo:nil repeats:NO];
I wrote this in above in separate NSObject class and created an object. I need some clarification on how run the two NSTimer simultaneously or keep track of all NSObjects.
Object creation in viewcontroller is
#property(nonatomic,strong)Toast *toast;
No need to keep the istance of timer in a ivar for your purpose. Use the userinfo: parameter to pass the view you mean to hide when the timer fires, like this:
[NSTimer scheduledTimerWithTimeInterval:(4.0f)
target:self
selector:#selector(xxxx)
userInfo:yourView repeats:NO];
Then in your selector retrieve the view from the userInfo and hide it. You can find a working sample here, line 37.

iPhone: NSTimer

Have a question...
I have Timer
[NSTimer scheduledTimerWithTimeInterval:120
target:self
selector:#selector(action1:)
userInfo:nil
repeats:YES];
But when I move to another screen of my app I want to change selector...How can I change selector ? I know that I can stop my timer and set a new one, but I don't wont to reset a time remained to fire action...Thanks....
You can't. NSTimer takes its targeting information in its instantiation methods, and doesn't expose any properties to modify that later.
You're going to have to invalidate this timer and create a new one on the new target.
It looks like the selector is immutable. I would wrap this functionality into it's only tiny class with a setSelector method. Internally, create the NSTimer with a private selector. Inside that method, call the external selector that's been set using the setSelector method.
You might call a generic selector that, depending on the page shown, calls other methods:
[NSTimer scheduledTimerWithTimeInterval:120
target:self
selector:#selector(selectorDispatcher)
userInfo:nil
repeats:YES];
and than obviously your method selectorDispatcher will look something like:
- (void) selectorDispatcher{
if(pageshown1)
[self callmethod1];
else
[self callmethod2];
}
I think this should work...let me know!

Touch handling not responding after NSTimer invalidate

I am creating a repeating NSTimer object that calls the -Loop() method every iteration of the run loop:-
NSTimer *loopTimer = [NSTimer scheduledTimerWithTimeInterval:TIMER_INTERVAL target:self selector:#selector(Loop) userInfo:nil repeats:YES];
Within Loop() I am invalidating the timer when it becomes necessary:-
[loopTimer invalidate];
However, after using -invalidate(), the Touch handling methods -touchesBegan(), -touchesEnded() stop responding to touch events. Does NSTimer affect the run loop to somehow?
what else you are using in loop method...
I am not sure what problem exactly you have.Anyway try this...
You can use schedular method..
[self schedule:#selector(loop) interval:TIMER_INTERVAL];
If you unscheduling with in the same function,you can use
[self unschedule:_cmd];
otherwise,
You can use [self unschedule:#selector(loop)];
This sounds like you didn't correctly retain the view or have released it once too often. A NSTimer retains its target object, and once you invalidate a timer it releases its target object. In your case, that seems to make the retain counter drop to 0 and it thus gets deallocated.
You can verify this by adding a NSLog right in front of your [loopTimer invalidate]; and another one at the start of your view's dealloc. My bet is that you will see dealloc's log message immediately after your invalidate log.
No, it doesn't affect your runloop in anyway. Infact I checked it myself, after i invalidated the timer i was able to process touches on screen.So i guess problem is something else.
I seem to have fixed the problem by putting -invalidate() inside the -dealloc() method. So when i want end the loop i call [self.view removeFromSuperView] and this calls invalidate eventually.
Putting -invalidate() inside view lifecyle seems to deallocate the view...

Is this memory safe?

[NSTimer scheduledTimerWithTimeInterval:0.033 target:self selector:#selector(gameLoop)
userInfo:nil repeats:YES];
I don't do anything to dealloc or kill this timer after starting it.
Is it safe? Or will it cause me to leak memory?
It shouldn't leak memory. You're not retaining the timer. The run loop will retain it (I think), but it'll release it when it no longer needs it.
The timer is retained by the run loop, so you don't need to retain it yourself.
However the timer will retain its target, so as long as it's repeating and you don't invalidate it, your target object won't be deallocated. You'll need to choose a good time to call invalidate on it which will cause the run loop to release it.
Note that you shouldn't also retain the timer yourself, at the risk of a retain cycle.
(I borked an answer to this very question yesterday and got schooled on it. Trying to atone.)