在UIPopover中停止NSTimer

时间:2011-10-07 20:34:07

标签: iphone ios ipad nstimer

所以我有一个带有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];
    }

}

1 个答案:

答案 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