Stop an NSTimer In A UIPopover
So I have a UIPopover with an NSTimer in it. It has various BOOLS and properties to make other methods happen, but that's not important right now. What I want to know is, is there any way to release and invalidate the timer when the parent view of the popover has disappeared? I tried class methods to invalidate and release the timer, but they gave me SIGABRT and EXC_BAD_ACCESS warnings. I think it had something to do with the timer being to told to dealloc when it was already nil.
开发者_如何学CA couple extra factors: 1. The timer must stay valid and alloc'd when the popover is dismissed. 2. The timer must invalidate and dealloc when the parent view has disappeared.
Any suggestions?
CODE:
//@interface
NSTimer *clickTimer;
@property (nonatomic, retain) NSTimer *clickTimer;
//.m
- (IBAction)clickerPressed:(id)sender
{
if ([click isClicking] == YES) {
[clickTimer invalidate];
[clickTimer release];
clickTimer = nil;
// enable the idle timer when the clicking is turned off
[[UIApplication sharedApplication] setIdleTimerDisabled:NO];
[click setIsClicking:NO];
[clickerButton setBackgroundImage:[UIImage imageNamed:@"wood.png"] forState:UIControlStateNormal];
[clickerButton setTitle:@"Start" forState:UIControlStateNormal];
[clickStatus setText:[NSString stringWithFormat:@"%d",[click numberOfBeatsToDisplay]]];
[click setClickCount:0];
}
else {
// disable the idle timer while the metronome is clicking.
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
[click setIsClicking:YES];
[clickerButton setBackgroundImage:[UIImage imageNamed:@"wood.png"] forState:UIControlStateNormal];
[clickerButton setTitle:@"Stop" forState:UIControlStateNormal];
[[NSThread currentThread] setThreadPriority:1.0];
clickTimer = [[NSTimer scheduledTimerWithTimeInterval:[click clickRateInSeconds] target:self selector:@selector(click:) userInfo:nil repeats:YES]retain];
}
}
Releasing an object does not automatically assign nil to the pointer. Add clickTimer = nil;
after your release statement. This will prevent another method from accessing an invalid object if it attempts to release clickTimer.
To ensure that all of your methods properly set the clickTimer to nil, you might consider creating a method that invalidates the timer for you rather than having each method invalidate the timer:
- (void) invalidateClickTimer
{
// invalidate timer
if (clickTimer == nil)
return;
[clickTimer invalidate];
[clickTimer release];
clickTimer = nil;
// stop clicking
[[UIApplication sharedApplication] setIdleTimerDisabled:NO];
[click setIsClicking:NO];
[clickerButton setBackgroundImage:[UIImage imageNamed:@"wood.png"] forState:UIControlStateNormal];
[clickerButton setTitle:@"Start" forState:UIControlStateNormal];
[clickStatus setText:[NSString stringWithFormat:@"%d",[click numberOfBeatsToDisplay]]];
[click setClickCount:0];
return;
}
Then replace the following lines in - (IBAction)clickerPressed:(id)sender
if ([click isClicking] == YES) {
[clickTimer invalidate];
[clickTimer release];
clickTimer = nil;
// enable the idle timer when the clicking is turned off
[[UIApplication sharedApplication] setIdleTimerDisabled:NO];
[click setIsClicking:NO];
[clickerButton setBackgroundImage:[UIImage imageNamed:@"wood.png"] forState:UIControlStateNormal];
[clickerButton setTitle:@"Start" forState:UIControlStateNormal];
[clickStatus setText:[NSString stringWithFormat:@"%d",[click numberOfBeatsToDisplay]]];
[click setClickCount:0];
}
With this line:
if ([click isClicking] == YES) {
[self invalidateClickTimer];
}
Call the new method - (void) invalidateClickTimer
from the parent view's UIViewController. Probably in the method - (void)viewWillDisappear:(BOOL)animated
精彩评论