所以我有一个带有NSTimer的UIPopover。它有各种BOOLS和属性来使其他方法发生,但现在这并不重要。我想知道的是,当弹出窗口的父视图消失时,有没有办法释放和使计时器失效?我尝试了类方法来使计时器失效并释放,但是他们给了我SIGABRT和EXC_BAD_ACCESS警告。我认为它与定时器有关,当它已经为零时被告知dealloc。
一些额外的因素: 1.计时器必须保持有效并在弹出窗口解除时分配。 2.当父视图消失时,计时器必须无效并取消激活。
有什么建议吗?
代码:
//@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];
}
}
答案 0 :(得分:2)
释放对象不会自动为指针指定nil。在发布声明后添加clickTimer = nil;
。如果尝试释放 clickTimer ,这将阻止其他方法访问无效对象。
为确保您的所有方法都正确地将 clickTimer 设置为 nil ,您可以考虑创建一种方法,使您的计时器无效,而不是让每个方法使定时器:
- (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;
}
然后替换- (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];
}
这一行:
if ([click isClicking] == YES) {
[self invalidateClickTimer];
}
从父视图的UIViewController调用新方法- (void) invalidateClickTimer
。可能在方法- (void)viewWillDisappear:(BOOL)animated