Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 04-25-2011, 02:00 PM   #1 (permalink)
Registered Member
 
Join Date: Feb 2011
Posts: 54
Nekbeth is on a distinguished road
Default How to Cancel a Timer ?

I get crashed if I use this code: (trying to create an outlet for a button with a selector to a method that invalidates the Time).

Code:
- (IBAction) cancelTime: (id) sender
{
    [self performSelector:@selector(cancelIt:) withObject:nil];

}


- (void) cancelIt:(NSTimer*)timer    

{
    
    [timer invalidate];
    timer = nil;
    
    
}

What am I missing ??

Thanks

Last edited by Nekbeth; 04-25-2011 at 02:27 PM.
Nekbeth is offline   Reply With Quote
Old 04-25-2011, 02:07 PM   #2 (permalink)
Reading the Documentation
 
baja_yu's Avatar
 
Join Date: Sep 2010
Location: 45.255019,19.844908
Posts: 5,414
baja_yu has a spectacular aura about
Default

Your cancelIt method takes the timer as the parameter and you're not passing it any.
baja_yu is offline   Reply With Quote
Old 04-25-2011, 02:29 PM   #3 (permalink)
Registered Member
 
Join Date: Feb 2011
Posts: 54
Nekbeth is on a distinguished road
Default

Quote:
Originally Posted by baja_yu View Post
Your cancelIt method takes the timer as the parameter and you're not passing it any.
I don't understand, what do you mean by not "not passing it any"?

I have the invalid method to that timer but it's not responding
Nekbeth is offline   Reply With Quote
Old 04-25-2011, 02:45 PM   #4 (permalink)
Reading the Documentation
 
baja_yu's Avatar
 
Join Date: Sep 2010
Location: 45.255019,19.844908
Posts: 5,414
baja_yu has a spectacular aura about
Default

What timer?

Code:
- (IBAction) cancelTime:(id) sender {
    [self performSelector:@selector(cancelIt:) withObject:nil];
}


- (void) cancelIt:(NSTimer*)timer {
    [timer invalidate];
    timer = nil;
}
Where is your timer declared? Is it an instance variable and what's the ivar called?
baja_yu is offline   Reply With Quote
Old 04-25-2011, 02:46 PM   #5 (permalink)
Senior Member
iPhone Dev SDK Supporter
 
Join Date: Aug 2008
Location: Memphis, TN, USA
Age: 24
Posts: 3,983
smithdale87 is on a distinguished road
Send a message via AIM to smithdale87
Default

Pay special attention to the value in bold

Code:
- (void) cancelIt:(NSTimer*)timer    

{
    
    [timer invalidate];
    timer = nil;
    
    
}
You call the cancel method like this:
Code:
[self performSelector:@selector(cancelIt:) withObject:nil];
Here the nil gets passed in to your cancelIt: method as the timer parameter. This is always going the be nil, which explains why you can't cancel somethign that doesnt exist.


Edit: baja beat me to the punch
smithdale87 is offline   Reply With Quote
Old 04-25-2011, 03:18 PM   #6 (permalink)
Registered Member
 
Join Date: Feb 2011
Posts: 54
Nekbeth is on a distinguished road
Default

Quote:
Originally Posted by baja_yu View Post
What timer?

Code:
- (IBAction) cancelTime:(id) sender {
    [self performSelector:@selector(cancelIt:) withObject:nil];
}


- (void) cancelIt:(NSTimer*)timer {
    [timer invalidate];
    timer = nil;
}
Where is your timer declared? Is it an instance variable and what's the ivar called?

My timer is declared as an Instance method :

Code:
- (IBAction) cancelTime: (id) sender;
- (void) cancelIt:(NSTimer*) timer;
So guys, could please give a hand and write the code as it should be. Should I declare it as an instance variable of NSTimer ? The reason I'm declaring it in a instance method is because I had another similar method before.

that is :

Code:
- (IBAction) echoMinute: (id) sender;
- (void) echoIt2: (NSTimer *) timer;
and I implement them as this :

Code:
- (IBAction) echoMinute:(id)sender

{
    
    NSDate * time = timePicker.date;
    NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
    [dateFormatter setDateFormat:@"HH:MM:SS"];
    NSLog(@"date:%@", [dateFormatter stringFromDate:time]);
    NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    
    NSDateComponents *comps = [gregorian components:(NSHourCalendarUnit | NSMinuteCalendarUnit) fromDate:time];
    
    NSInteger hour = [comps hour];
    NSInteger minute = [comps minute];
    NSLog(@"Hour:%i", hour);
    NSLog(@"minute:%i", minute);
    NSInteger secs =hour * 60 * 60 + minute * 60;
    NSInteger mins = secs / 60;
    
    
    
    NSNumber *elapsedMinutes = [NSNumber numberWithInt:mins];
    NSDictionary *myMinute = [NSDictionary dictionaryWithObject:elapsedMinutes forKey:@"TotalMinutes"];
    
    [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(echoIt2:) userInfo:myMinute repeats:YES];
    
    
    // TIME CHOSEN  (1)
    
    label.text = [NSString stringWithFormat:@"Hours: %i, Min: %i", hour, minute];   
    
    
}



- (void) echoIt2:(NSTimer *)timer      //  MINUTES METHOD  (2)

{
    
    NSNumber *num = (NSNumber *) [[timer userInfo] valueForKey:@"TotalMinutes"];   //elapsed
    minutes++;
    
    NSInteger min = [num integerValue] - minutes;                                 //remaining
    NSLog(@"elapsed: %i, remaining: %i", minutes, min);
    
    if (min <=0) 
    {
        [timer invalidate];
    }
    

    label2.text = [NSString stringWithFormat:@"Minutes remaining: %i", min];
    
    
}

I'm just trying to create another button for the same Timer declared so I can stop it or cancel it.
Nekbeth is offline   Reply With Quote
Old 04-25-2011, 03:29 PM   #7 (permalink)
Senior Member
iPhone Dev SDK Supporter
 
Join Date: Aug 2008
Location: Memphis, TN, USA
Age: 24
Posts: 3,983
smithdale87 is on a distinguished road
Send a message via AIM to smithdale87
Default

Code:
 [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(echoIt2:) userInfo:myMinute repeats:YES];
It would be helpful if you create an instance variable and store this created timer in it. That way, when you go to cancel it, you have a pointer to it.
smithdale87 is offline   Reply With Quote
Old 04-25-2011, 03:36 PM   #8 (permalink)
Registered Member
 
Join Date: Feb 2011
Posts: 54
Nekbeth is on a distinguished road
Default

Quote:
Originally Posted by smithdale87 View Post
Code:
 [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(echoIt2:) userInfo:myMinute repeats:YES];
It would be helpful if you create an instance variable and store this created timer in it. That way, when you go to cancel it, you have a pointer to it.


OOh I see what missing now, your right.. I had not Timer, only a pointer.

I'll give a try. Thanks

By the way, do you know how to make the seconds stop at 60 and loop instead of showing 566 seconds remaining?
Nekbeth is offline   Reply With Quote
Old 04-25-2011, 05:15 PM   #9 (permalink)
Just helping out.
 
Domele's Avatar
 
Join Date: Feb 2011
Posts: 2,565
Domele is on a distinguished road
Default

What do you mean like when it reached 60 it goes back down to 0 again and starts its way up back to 60? If so just say something like
Code:
 if (seconds > 60) {
seconds = seconds - 60;
}
Domele is offline   Reply With Quote
Old 04-25-2011, 06:08 PM   #10 (permalink)
Registered Member
 
Join Date: Feb 2011
Posts: 54
Nekbeth is on a distinguished road
Default

Quote:
Originally Posted by Domele View Post
What do you mean like when it reached 60 it goes back down to 0 again and starts its way up back to 60? If so just say something like
Code:
 if (seconds > 60) {
seconds = seconds - 60;
}

Thanks Domele, it's the other way around, when it reaches 0 it goes back to 60. About the other thing, I was able to call the timer method, here is the code:

Code:
- (IBAction) cancelTime: (id) sender
{
    
    
    
   [NSTimer scheduledTimerWithTimeInterval:0
                                     target:self 
                                   selector:@selector(cancelIt:) 
                                   userInfo:nil 
                                    repeats:NO];
    
    


}


- (void) cancelIt:(NSTimer*)timer    // A VERDE

{
    [timer invalidate];
    
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"An Alert!" 
                                                   delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
    [alert release];

The alert is just a test, It works fine when I press the button, but I don't think I'm accessing the timer's info because the "timer invalidate" is not responding. So my guess is that I need to add something inside the "userInfo parameter" in the declaration, what do you think?
Nekbeth is offline   Reply With Quote
Old 04-25-2011, 07:59 PM   #11 (permalink)
Cocoa Junkie
 
Duncan C's Avatar
 
Join Date: Dec 2008
Location: Northern Virginia
Posts: 6,003
Duncan C has a spectacular aura about
Default

Quote:
Originally Posted by Nekbeth View Post
Thanks Domele, it's the other way around, when it reaches 0 it goes back to 60. About the other thing, I was able to call the timer method, here is the code:

Code:
- (IBAction) cancelTime: (id) sender
{
    
    
    
   [NSTimer scheduledTimerWithTimeInterval:0
                                     target:self 
                                   selector:@selector(cancelIt:) 
                                   userInfo:nil 
                                    repeats:NO];
    
    


}


- (void) cancelIt:(NSTimer*)timer    // A VERDE

{
    [timer invalidate];
    
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"An Alert!" 
                                                   delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
    [alert release];

The alert is just a test, It works fine when I press the button, but I don't think I'm accessing the timer's info because the "timer invalidate" is not responding. So my guess is that I need to add something inside the "userInfo parameter" in the declaration, what do you think?

This first code is wrong:

Code:
- (IBAction) cancelTime: (id) sender
{
  [NSTimer scheduledTimerWithTimeInterval:0
    target:self 
    selector:@selector(cancelIt:) 
    userInfo:nil 
    repeats:NO];
}

That code creates a timer, but does not save a pointer to that timer. Thus, you have no way to stop the timer.

In your class's .h file, add an instance variable theTimer:

NSTimer* theTimer;

Change your cancelTime method to save the timer into that instance variable:


Code:
- (IBAction) cancelTime: (id) sender
{
  theTimer = [NSTimer scheduledTimerWithTimeInterval:0
    target:self 
    selector:@selector(cancelIt:) 
    userInfo:nil 
    repeats:NO];
}

And in your cancelIt method, use your theTimer instance variable to cancel the timer:


Code:
- (void) cancelTimer;    // Do not include a time in this method's parameters
{
  [theTimer invalidate]; //This is the timer object we saved in "cancelTime", above
  theTimer = nil; //Set "theTimer" to nil since it's no longer valid.
  UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"An Alert!" 
    delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
  [alert show];
  [alert release];
__________________
Regards,

Duncan C
WareTo

Check out our apps in the Apple App store


Check out this password generator app that shows various techniques including using a data container singleton object to share data between objects in your project.

See this tutorial on using UIView animations and layer animations:

See this thread on generating random, non-repeating text

Check out a very cool Macintosh Kaleidoscopes app called ScopeWorks that we released to the Mac App store.
Duncan C is offline   Reply With Quote
Old 04-25-2011, 09:14 PM   #12 (permalink)
Registered Member
 
Join Date: Feb 2011
Posts: 54
Nekbeth is on a distinguished road
Default

Great, thank you Duncan. I really needed that variable. Only thing is that I did not create a new timer, i used the old one with the new variable, then I used it like you pointed out. Cancel button, finally worked .

* Should I call a refresh or reload method on the timer after I cancel ?
Nekbeth is offline   Reply With Quote
Old 04-26-2011, 07:11 AM   #13 (permalink)
Cocoa Junkie
 
Duncan C's Avatar
 
Join Date: Dec 2008
Location: Northern Virginia
Posts: 6,003
Duncan C has a spectacular aura about
Default

Quote:
Originally Posted by Nekbeth View Post
Great, thank you Duncan. I really needed that variable. Only thing is that I did not create a new timer, i used the old one with the new variable, then I used it like you pointed out. Cancel button, finally worked .

* Should I call a refresh or reload method on the timer after I cancel ?

You can't reuse timers. After you invalidate them you have to create a new one.

I generally don't retain timers, since when you schedule them, the system retains them. I save them in a non-retained property. I'll sometimes set up a custom setter that invalidates the old timer, like this:


Code:
-(void) setTimer: (NSTimer*) newValue;
{
  if (timer != newValue)
  {
  [timer invalidate];
  timer = newValue;
  }
}

Then, to cancel a timer, you can just use code like this:

Code:
self.timer = nil;
__________________
Regards,

Duncan C
WareTo

Check out our apps in the Apple App store


Check out this password generator app that shows various techniques including using a data container singleton object to share data between objects in your project.

See this tutorial on using UIView animations and layer animations:

See this thread on generating random, non-repeating text

Check out a very cool Macintosh Kaleidoscopes app called ScopeWorks that we released to the Mac App store.
Duncan C is offline   Reply With Quote
Old 04-26-2011, 01:48 PM   #14 (permalink)
Registered Member
 
Join Date: Feb 2011
Posts: 54
Nekbeth is on a distinguished road
Default

Quote:
Originally Posted by Duncan C View Post
You can't reuse timers. After you invalidate them you have to create a new one.

I generally don't retain timers, since when you schedule them, the system retains them. I save them in a non-retained property. I'll sometimes set up a custom setter that invalidates the old timer, like this:


Code:
-(void) setTimer: (NSTimer*) newValue;
{
  if (timer != newValue)
  {
  [timer invalidate];
  timer = newValue;
  }
}

Then, to cancel a timer, you can just use code like this:

Code:
self.timer = nil;

Ok Duncan, I have try to follow up your code. Here is what I got :

I first declare two variables for my timers (original timer and new timer) :

.h
Code:
NSTimer *myTimer; 
NSTimer *newTimer;
then I add the methods for each timer. Here is the method for the new timer:

Code:
//NEW TIMER
- (IBAction) newActionTimer: (id)sender;
- (void) echoNewActionTimer: (NSTimer *) timer2;

then in .m , I implement the methods, here is the method for new timer:


Code:
                           ---------------- NEW TIMER -----------------


- (IBAction) newActionTimer: (id)sender
{ 
    
    newTimer = [NSTimer scheduledTimerWithTimeInterval:0 target:self selector:@selector(echoNewActionTimer:) userInfo:nil repeats:NO];


}



- (void) echoNewActionTimer: (NSTimer *)timer2

{
    
    [myTimer invalidate];                          // Timer seems to work because it pauses the logged timed elapsed
    myTimer = nil;
    
    
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"Invalidate" 
                                                   delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
    [alert release];
    
    
    
    //  is my newTimer On right now ?? 
}

The result is that the original Timer stops or invalidates but I still don't know if my new Timer is On. The new Timer also needs to be filled with userInfo, I'll do that after I know it's being called.

Please, if you see any fundamental errors, let me know..
Nekbeth is offline   Reply With Quote
Reply

Bookmarks

Tags
timer

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 349
11 members and 338 guests
dansparrow, iOS.Lover, lorrettaui53, Nobbsy, oztemel, pbart, PlutoPrime, samdanielblr, sledzeppelin, thephotographer, Trickphotostudios
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,663
Threads: 94,120
Posts: 402,897
Top Poster: BrianSlick (7,990)
Welcome to our newest member, LezB44
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 01:51 AM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0