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.
A 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:
Then replace the following lines in
- (IBAction)clickerPressed:(id)senderWith this line:
Call the new method
- (void) invalidateClickTimerfrom the parent view’s UIViewController. Probably in the method- (void)viewWillDisappear:(BOOL)animated