Tick timer in Objective C / iPhone? [duplicate] - ios

This question already has answers here:
How do I use NSTimer?
(6 answers)
Closed 9 years ago.
I am making a Simon Says app to learn more about Objective C.
My SimonSaysViewController has 4 buttons. Their image needs to change accordingly when the pattern is being shown to the user.
A fixed interval timer will be absolutely fine.
I just cannot seem to find an example.
I basically would want a sort of setup like:
TimerTicked callback when I can do the image swapping logic.
Ideally, the TimerTicked method would be a method of my SimonSaysViewController.
How would this be done?
Thanks

NSTimer is your friend! Add an NSTimer property to your SimonSaysViewController.
#property (strong, nonatomic) NSTimer *tickTockTimer;
Depending on when you want the timer to start, you'll want to set up the timer then. Say you wanted the timer to start when the view first appears:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.tickTockTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(timerFired:) userInfo:nil repeats:YES];
}
Then implement the timerFired method and do what you need there.
- (void)timerFired:(NSTimer *)timer {
//change the image.
}
Don't forget to invalidate the timer when you are done.
- (void) viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.timer invalidate];
self.timer = nil;
}

This kind of thing usually works for me
NSDate *fireDate = [NSDate dateWithTimeIntervalSinceNow:2.0]; // 2 sec from now
NSTimer *self.timer = [[NSTimer alloc] initWithFireDate:fireDate interval:5 target:self selector:#selector(timerDidTick) userInfo:nil repeats:YES]; // fire 5 sec apart
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:self.timer forMode:NSDefaultRunLoopMode];

Related

NSTimer called twice

timer inside init method calling itself twice after its interval of 10seconds.Can anybody please tell me how to stop this ? Thanks in advance.
- (id)init {
if (self = [super init]) {
timer=[NSTimer scheduledTimerWithTimeInterval:10 target:self selector:#selector(serviceCalling) userInfo:nil repeats:YES];
//[timer fire];
//NSDefaultRunLoopMode
//[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}
return self;
}
-(void)serviceCalling{
NSLog(#"Inside");
}
Are you constructing this object more than once? Given the code you have posted, that's the only explanation (unless you are confusing the repeated one 10 seconds later).
Put an NSLog in the init.

NSTimer Not Firing? [duplicate]

This question already has answers here:
NSTimer not firing
(3 answers)
Closed 8 years ago.
My timer only fires once even though I have repeat initialized as YES. I want my timer to fire every 6 seconds? What is the problem?
#interface TCAMyScene (){
NSTimer *bombTimer;
}
bombTimer = [[NSTimer alloc] initWithFireDate:[NSDate date] interval:6 target:self selector:#selector(setBomb) userInfo:nil repeats:YES];
[bombTimer fire];
Solution:
bombTime = [NSTimer scheduledTimerWithTimeInterval:6 target:self selector:#selector(setBomb) userInfo:nil repeats:YES];
From the documentation for NSTimer:
You must add the new timer to a run loop, using addTimer:forMode:.
Upon firing, the timer sends the message aSelector to target. (If the
timer is configured to repeat, there is no need to subsequently re-add
the timer to the run loop.)
You're better calling:
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats
As this will add it to the current run loop in the default mode (which is usually what you want, unless there's an explicit need for a different run loop or mode)

NSTimer does not stop

[self performSelectorInBackground:#selector(method) withObject:nil];
-(void)method
{
timer1 = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(getLastImageName1) userInfo:nil repeats:YES];
runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:timer1 forMode:NSRunLoopCommonModes];
[runLoop run];
}
-(void)viewdidunload
{
[timer1 invalidate];
timer1=nil;
}
I start Timer in HomeViewController even I invalidate, it keeps running in OtherViewController. What is wrong with my code?
First of all, when you're overriding life cycle methods, you should include a call to the super version of that method.
Second of all, Objective-C is case sensitive, so even if your app would try to call the life-cycle even, viewDidUnload, your method would simply never be called because that's what you titled your method.
Third of all, viewDidUnload was deprecated in iOS 6.0 and shouldn't be used at all by this point unless you're going way out of your way to support backward compatibility. It will never be called in iOS 6.0 and greater.
If you want the timer to stop when the user navigates away from the current view, you'll want something like this:
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
if (timer1.isValid) {
[timer1 invalidate];
}
timer1 = nil;
}
If you're looking for something else, you'll need to elaborate on what it is you want to accomplish exactly.
If you ARE working on a pre-iOS 6.0 project, for whatever reason, the reason your method isn't being called is at least in part because it is spelled wrong. Again, Objective-C is case sensitive. Your method name should be spelled viewDidUnload.
For future reference, the question shouldn't really be "why isn't my timer invalidating?" You should have start by using breakpoints or NSLog statements to determine whether or not your method, viewdidunload, which tries to invalidate the timer even fires. When you find out it's not being called, do a search to ask "How come viewdidunload isn't called?" Then you'll go fix the capitalization problem and the problem will (probably) remain, so do some more research. And if at the end, you still can't figure it out, as a worst case scenario, the post question should be "how come viewdidunload isn't called?"
timer1 = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(getLastImageName1:) userInfo:nil repeats:YES];
set colon for function in selector
-(void) getLastImageName1 :(NSTimer*)timer1
{
//Do your all process and invalidate after completion
[timer1 invalidate];
}
or if you want to remove timer after moving to next view controller use how #nhgrif mentioned
- (void)viewDidDisappear:(BOOL)animated
{
[timer1 invalidate];
}
[self performSelector:#selector(method) withObject:nil afterDelay:0.0];
-(void)method
{
timer1 = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(getLastImageName1) userInfo:nil repeats:YES];
runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:timer1 forMode:NSRunLoopCommonModes];
[runLoop run];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[timer1 invalidate];
timer1=nil;
}
There is no need to add the timer (again) on the main run loop. Or is it necessary for You to run it also in commonModes? For me it was never necessary.
From the NSTimer Documentation:
scheduledTimerWithTimeInterval:invocation:repeats:
Creates and returns a new NSTimer object and schedules it on the
current run loop in the default mode.
Since the NSRunLoop Documentation points out that you can add timer on several run loop modes, maybe this is the problem.
addTimer:forMode:
Discussion You can add a timer to multiple input modes. While running
in the designated mode, the receiver causes the timer to fire on or
after its scheduled fire date. Upon firing, the timer invokes its
associated handler routine, which is a selector on a designated
object.
Also I don't get why you are invoking the timer creation with performSelector?
I just wrote a minimalistic sample. thats totally working!
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(doWork:) userInfo:Nil repeats:YES];
}
- (void)viewDidDisappear:(BOOL)animated{
[self.timer invalidate];
[super viewDidDisappear:animated];
}
- (void) doWork:(id) userInfo
{
NSLog(#"Working again");
}
Hope this helps.
-(void)viewDidUnload is a delegate which fires on memory warning only and is deprecated after iOS 6. It will also never fire on the simulator.
Stop timer in
- (void)viewWillDisappear:(BOOL)animated
or in
- (void)viewDidDisappear:(BOOL)animated

iOS - Do an action every second [duplicate]

This question already has answers here:
Update a label with speed every x seconds
(2 answers)
Closed 9 years ago.
I want to make an action when every second is passed, for example I got a label and I want it every second to do this :
theLabel.text = #"Hey";
So, how I'll do it?
I think I'll need to use the NSTimer right?
Thanks in Advance
Just use a NSTimer:
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(doSomething:) userInfo:nil repeats: YES];
And to stop it:
[timer invalidate];
Find the documentation here:
NSTimer Doc
A "plan B" solution:
[self performSelector:#selector(foo) withObject:nil afterDelay:{some time interval}];
-(void)foo
{
//do something..
[self performSelector:#selector(foo) withObject:nil afterDelay:{some time interval}];
}
Yes #kevin you are right NSTimer is the best
just initialize your timer on did load
NSTimer *timerCounter = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(doMyWork) userInfo:nil repeats: YES]; //make repeats YES
and do the below
-(void)doMyWork
{
theLabel.text = #"Hey";
// Or what ever you want to do
}

How to stop NStimer event? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
NSTimer doesn't stop
In my application I am using NStimer to call an animation function every 3 seconds. I want to stop this timer and called another event while the timer is still running. Is this possible?
#interface
NSTimer *autoTimer;
#implementation
// Start timer
autoTimer = [NSTimer scheduledTimerWithTimeInterval:(3.0)
target:self
selector:#selector(autoTimerFired:)
userInfo:nil
repeats:YES];
// Stop timer:
[autoTimer invalidate];
autoTimer = nil;
First, you want to keep a pointer to the timer
self.packetTimer = [NSTimer timerWithTimeInterval:CONNECTION_TIMEOUT target:self selector:#selector(connectionTimeout:) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:packetTimer forMode:NSDefaultRunLoopMode];
If somewhere else in your code you want to cancel it, just call:
[self.packetTimer invalidate];
self.packetTimer = nil;

Resources