所以我有一个带有NSTimer的UIPopover。它具有各种BOOLS和属性来实现其他方法,但是现在这并不重要。我想知道的是,当弹出窗口的父视图消失时,有什么方法可以释放计时器并使计时器无效吗?我尝试使用类方法来使计时器无效并释放计时器,但是它们给了我SIGABRT和EXC_BAD_ACCESS警告。我认为这与计时器被告知在已经为零时取消分配有关。

几个额外的因素:
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];
    }


}

最佳答案

释放对象不会自动将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

关于iphone - 在UIPopover中停止NSTimer,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7692602/

10-09 16:32