Stop Method Execution after 5 Minute - objective-c

How can i stop the execution of the method after a certain time?
I am calling method as below:
[NSTimer scheduledTimerWithTimeInterval:5.0f
target:self
selector:#selector(doSomeTask) userInfo:nil repeats:YES];
Here i have given interval of 5 Seconds. So this method will get called after every 5 seconds, So once the reaches to specified time i want to stop this method execution.

Take a counter variable, and increase in every call by 5 (as time interval is 5 sec ) like
counter = counter+5;
-(void) doSomeTask {
if (counter<=60) { // 5 min = 300 300/5 = 60
// Write method body here
counter = counter+5
}
else {
[timer invalidate];
}
}

If you want to stop execution of the method after 5 min. Then you can add code like this
#interface YourClass () {
int count;
}
#end
-(void)viewDidLoad {
count = 5;
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0f target:self selector:#selector(doSomeTask) userInfo:nil repeats:YES];
}
-(void) doSomeTask
{
count = count + 5;
if (count==300)
{
[timer invalidate];
timer=nil;
}
}

#define TIMER_LIFE_IN_SECONDS 300.0
#interface YourClass () {
NSTimeInterval _startTime;
}
self.timer = [NSTimer scheduledTimerWithTimeInterval:5.0f target:self selector:#selector(doSomeTask) userInfo:nil repeats:YES];
_startTime = [NSDate timeIntervalSinceReferenceDate];
- (void) doSomeTask
{
// do thing
NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate];
if (now - _startTime > TIMER_LIFE_IN_SECONDS) {
[self.timer invalidate];
self.timer = nil;
}
}

you can try like this
NSTimer *reachTimer;
NSInteger secondsLeft;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
secondsLeft = 0;
reachTimer = [NSTimer scheduledTimerWithTimeInterval:5.0f target:self selector:#selector(updateCounter:) userInfo:nil repeats:YES];
}
-(void)updateCounter:(NSTimer *)theTimer{
secondsLeft = secondsLeft+5;
if(secondsLeft>=300) // 60sec * 5min= 300
{
[reachTimer invalidate];
}
}

Try this;
int count;
NSTimer *timer;
-(void)startTimertillLimit:(int)limit {
count = 0;
timer = [NSTimer scheduledTimerWithTimeInterval:5
target:self
selector:#selector(doSomething:)
userInfo:[NSString stringWithFormat:#"%d",limit]
repeats:YES];
}
-(void)doSomething:(NSTimer*)sender
{
int limit = (int)[sender.userInfo intValue];
count = count + 5;
if (count > limit)
{
[timer invalidate];
timer=nil;
count = 0;
}
}

Try to create NSTimer that will be called after some time only once :
NSTimer *previous [NSTimer scheduledTimerWithTimeInterval:5.0f target:self selector:#selector(doSomeTask) userInfo:nil repeats:YES];
[NSTimer scheduledTimerWithTimeInterval:300 target:self selector:#selector(stopPrevious) userInfo:nil repeats:NO];
-(void)stopPrevious{
[previous invalidate];
}

Related

Objective C : NStimer- How to stop timer after n hours

I have started the timer using below call, and need to stop it after n hours
self.timer = [NSTimer scheduledTimerWithTimeInterval:20 target:self selector:#selector(sendLocationUpdates) userInfo:nil repeats:YES];
The solution I can thin of get the current time when timer start and keep adding time till threshold reaches. Or is there any better way to stop timer?
Add an instance variable to the class to store the start time of the timer:
YourClass.m:
#interface YourClass () {
NSTimeInterval _startTime;
}
#end
Record the current time when creating the timer:
self.timer = [NSTimer scheduledTimerWithTimeInterval:20 target:self selector:#selector(sendLocationUpdates) userInfo:nil repeats:YES];
_startTime = [NSDate timeIntervalSinceReferenceDate];
and test the current time in the sendLocationUpdates method:
#define TIMER_LIFE_IN_SECONDS 3000.0
- (void)sendLocationUpdates
{
// do thing
NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate];
if (now - _startTime > TIMER_LIFE_IN_SECONDS) {
[self.timer invalidate];
self.timer = nil;
}
}
simple solution
declare two properties
#property NSInteger counter;
#property NSTimeInterval interval;
set the counter to 0 before starting the timer
self.counter = 0;
self.interval = 20.0;
self.timer = [NSTimer scheduledTimerWithTimeInterval:self.interval target:self selector:#selector(sendLocationUpdates) userInfo:nil repeats:YES];
in the sendLocationUpdates method increment the counter
- (void)sendLocationUpdates
{
counter++;
if (counter == 4 * (3600 / self.interval)) {
[self.timer invalidate];
self.timer = nil;
}
// do other stuff
}
with a given time interval of 20 seconds the timer fires 180 times per hour.
In the example the timer stops after 4 hours

Change NSTimer interval after a certain number of fires

In the following code, the NSTimer interval is set at 1 second between each picture. My goal is to change the interval after the first two pictures, hello.png and bye.png, to 4 seconds.
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *imageNames = #[#"hello.png",#"bye.png",#"helloagain.png",#"bye again"];
self.images = [[NSMutableArray alloc] init];
for (int i = 0; i < imageNames.count; i++) {
[self.images addObject:[UIImage imageNamed:[imageNames objectAtIndex:i]]];
}
self.animationImageView = [[UIImageView alloc] initWithFrame:CGRectMake(60, 95, 86, 90)];
self.animationImageView.image = self.images[0];
[self.view addSubview:self.animationImageView];
self.animationImageView.userInteractionEnabled = TRUE;
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(changeImage:) userInfo:nil repeats:YES];
}
-(void)changeImage:(NSTimer *) timer {
if (counter == self.images.count - 1 ) {
counter = 0;
}else {
counter ++;
}
self.animationImageView.image = self.images[counter];
}
my goal is to change the interval
You cannot change a timer in any way. To change the firing interval, invalidate and destroy the timer and make a new timer with the new interval.
To do that, you will need to have kept a reference to the timer, as a property of your view controller (something that you have fatally failed to do in your implementation - you would have had no way to stop the timer, and you would have crashed if your view controller ever went out of existence, or else your view controller would have leaked because the timer retains it).
Make the timer object a member variable. Initially set animation time as 1 second. In the callback invalidate the timer and create a new one with 1 or 4 seconds depending on the counter.
#interface ViewController ()
#property (strong,nonatomic) NSMutableArray *images;
#property (strong,nonatomic) UIImageView *animationImageView;
{
NSTimer *_timer;
}
#end
#implementation ViewController {
NSInteger counter;
}
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *imageNames = #[#"hello.png",#"bye.png",#"helloagain.png",#"bye again"];
self.images = [[NSMutableArray alloc] init];
for (int i = 0; i < imageNames.count; i++) {
[self.images addObject:[UIImage imageNamed:[imageNames objectAtIndex:i]]];
}
self.animationImageView = [[UIImageView alloc] initWithFrame:CGRectMake(60, 95, 86, 90)];
self.animationImageView.image = self.images[0];
[self.view addSubview:self.animationImageView];
self.animationImageView.userInteractionEnabled = TRUE;
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(bannerTapped:)];
singleTap.numberOfTapsRequired = 1;
singleTap.numberOfTouchesRequired = 1;
[self.animationImageView addGestureRecognizer:singleTap];
_timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(changeImage:) userInfo:nil repeats:YES];
}
-(void)changeImage:(NSTimer *) timer {
[_timer invalidate];
if (counter == self.images.count - 1 ) {
counter = 0;
}else {
counter ++;
}
if(counter == 0 || counter == 1)
{
_timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(changeImage:) userInfo:nil repeats:YES];
}
else if(counter == 2 || counter == 3)
{
_timer = [NSTimer scheduledTimerWithTimeInterval:4 target:self selector:#selector(changeImage:) userInfo:nil repeats:YES];
}
self.animationImageView.image = self.images[counter];
}
The best/simpliest way :
-(void)Timer{
// Do what you want here
// modify the frequency value if you want.
[NSTimer scheduledTimerWithTimeInterval:frequence target:self selector:#selector(Timer) userInfo:nil repeats:NO];
}
Frequence is a variable that contains the interval.
You just need to call Timer method by yourself the first time ;)
For you, it would give
-(void)changeImage{
if (counter == self.images.count - 1 )
counter = 0;
else
counter ++;
frequence = (counter < 2)?1:4;
self.animationImageView.image = self.images[counter];
[NSTimer scheduledTimerWithTimeInterval:frequence target:self selector:#selector(changeImage) userInfo:nil repeats:NO];
}

Displaying NSTimer value on label

There is a button and a label in my project.After clicking the button i need to start a NSTimer which displays it's value on label.For example 1sec.I am not sure whether timer returns value.is there any other way to do this?.
in the function of button click
{
NSTimer *t;
t=[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(showTimer) userInfo:nil repeats:YES];
}
in showTimer function
-(void)showTimer{
static int i=0;
static int min=0;
if(i>=59){
i=0;
min++;
} else {
i++;
}
yourLabel.text=[NSString stringWithFormat:#" %d:%d ",min,i];
}
NSTimer *aTimer = [NSTimer timerWithTimeInterval:(1) target:self selector:#selector(timerFired:) userInfo:nil repeats:YES];
NSRunLoop *runner = [NSRunLoop currentRunLoop];
[runner addTimer:aTimer forMode: NSDefaultRunLoopMode];
int i=0;
- (void)timerFired:(NSTimer*)theTimer
{
if(condition)
{
// timer repeat
// your actions
i++;
int conseconds = i % 60;
int conminutes = (i / 60) % 60;
timelable.text=[NSString stringWithFormat:#"%02d:%02d", conminutes,conseconds];
[theTimer isValid];
}
else
{
// your actions
//timer stopped
[theTimer invalidate];
}
}

Why does this NSTimer crash?

http://www.youtube.com/watch?v=5al6qqRzzQg when i click on the start more than once???
what will i need to do
#import "FirstViewController.h"
#implementation FirstViewController
-(IBAction)start;{
myticker = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(showActivity) userInfo:nil repeats:YES];
}
-(IBAction)stop;{
[myticker invalidate];
}
-(IBAction)reset;{
time.text = #"0";
}
-(void)showActivity;{
int currentTime = [time.text intValue];
int newTime = currentTime + 1;
time.text = [NSString stringWithFormat:#"%d", newTime];
}
- (void)didReceiveMemoryWarning
Change your start and stop methods to this:
-(IBAction)start;{
[myticker invalidate];
myticker = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(showActivity) userInfo:nil repeats:YES];
}
-(IBAction)stop;{
[myticker invalidate];
myticker = nil;
}
That will stop it crashing. Also, you should add this:
-(void)dealloc
{
[myticker invalidate];
}
add a bool variable to the header of your class, like timerIsActive
-(IBAction)start;{
if (!timerIsActive) {
myticker = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(showActivity) userInfo:nil repeats:YES];
timerIsActive = YES;
}
}
-(IBAction)stop;{
timerIsActive = NO;
[myticker invalidate];
}

NSTimer code is executing forever

Here is my code. I expected the timer to stop in 5 second after it starts but it doesn't. What is wrong here ?
-(void)loadView
{
NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate];
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.0
target:self
selector:#selector(targetMethod:)
userInfo:nil
repeats:YES];
if([NSDate timeIntervalSinceReferenceDate] - startTime >= 5) {
[timer invalidate];
}
}
-(void)targetMethod:(NSTimer *)timer {
NSLog(#"bla");
}
NSDate's timeIntervalSinceReferenceDate is, by default, returning January 1st, 2001. Subtracting the same values will always be 0.
Apple's documentation:
https://developer.apple.com/library/mac/ipad/#documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html
Here's an idea:
In your .h
#interface MyClass : NSObject
#property (nonatomic, retain) NSTimer *timer;
- (void)targetMethod:(NSTimer *)timer;
- (void)cancelTimer;
#end
In your .m
#implementation MyClass
#synthesize timer;
-(void)loadView
{
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.0
target:self
selector:#selector(targetMethod:)
userInfo:nil
repeats:YES];
[self performSelector:#selector(cancelTimer) withObject:nil afterDelay:5.0];
}
-(void)cancelTimer {
[self.timer invalidate];
}
-(void)targetMethod:(NSTimer *)timer {
NSLog(#"bla");
}
This is short and simple:
NSDate *endtime = [NSDate dateWithTimeIntervalSinceNow:5];
[NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:#selector(timerTick:)
userInfo:endtime
repeats:YES];
-(void)timerTick:(NSTimer*)timer
{
NSLog(#"timer tick");
if ( [timer.userInfo timeIntervalSinceNow] < 0 )
{
[timer invalidate];
NSLog(#"invalidating timer");
}
}
Your time difference is always 0 so you never invalidate it!
Try setting startTime before you set the timer.
You get the 'startTime' value and the value you compare it to are identical. Your calculation will always give 0. You must store the 'startTime' in your loadView method and then use it in the calculation.