1

我现在正在学习 Mac OS X 编程。我的第一个项目是写一个简单的秒表。我知道你可以使用 NSTimer,但我想如果我自己完成所有工作,我会学到更多。该应用程序运行良好。但是在恢复秒表后,它会跳过每一秒的数字..

这里的代码:

- (IBAction)stop:(id)sender {
    started = FALSE;
    NSLog(@"Stop pressed: %i", started);
}

- (IBAction)start:(id)sender {
    if(!started){
        started = TRUE;
        [self tock:nil];  
    }
    else {
        started = FALSE; 
    }
}

- (void) tock:(id)sender { 
     if(started == TRUE) {
         seconds++;
     };

     [self performSelector:@selector(tock:) withObject:(self) afterDelay:(1.0)];
     _anzeige.stringValue = [NSString stringWithFormat:(@"%i"), seconds];
}
4

4 回答 4

1

第 1 步:在 .h 文件中声明以下两个变量

NSTimer *secondTimer;
int seconds;

第2步:然后将秒初始化为0

- (void)viewDidLoad
{
    seconds = 0;
}

第 3 步:编写以下方法并为各自的 Start 和 Stop 方法分配 IBOutlets

- (IBAction)stop:(id)sender
{
    // Check if time is enable stop it first    
    if([secondTimer isValid])
    {
        [secondTimer invalidate];
        secondTimer = nil;
    }
}

- (IBAction)start:(id)sender
{
    // Check if time is enable stop it first
    if([secondTimer isValid])
    {
        [secondTimer invalidate];
        secondTimer = nil;
    }

    // now start a new timer
    secondTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(tock) userInfo:nil repeats:YES];
}

- (void) tock
{
    seconds++;
    NSLog(@"%d",seconds);
    // if you want to display second in UILabel uncomment following line
    //[lbl setText:[NSString stringWithFormat:@"%d",seconds]];
}
于 2013-03-27T18:04:37.353 回答
0

像这样尝试并使用 NSDate 变量 lObjstrt 中的开始时间和

NSTimeInterval lTimeInterval=[lObjCurrentDateStr timeIntervalSinceDate:lObjstrt];
NSDate *lObjTimerDatePtr =[NSDate dateWithTimeIntervalSince1970:lTimeInterval];
NSDateFormatter *lObjDateFormatterPtr = [[NSDateFormatter alloc] init];
[lObjDateFormatterPtr setDateFormat:@"mm:ss.SS"];
[lObjDateFormatterPtr setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *m_cObjSprintTimePtr=[lObjDateFormatterPtr stringFromDate:lObjTimerDatePtr];
NSString *m_cObjSprintTimerValuePtr = [NSString stringWithFormat:@"%@ secs", self.m_cObjSprintTimePtr];

有了这个,您可以相应地获取计时器并尝试在停止后让计时器休息,例如:

if((NSTimer *)nil != m_cObjSprintTimerPtr) {
    [m_cObjSprintTimerPtr invalidate];
    m_cObjSprintTimerPtr = (NSTimer *)nil;
}
于 2013-03-27T10:18:17.517 回答
0

您需要取消performSelector:withObject:afterDelay:通话。否则,每次调用时它们都会堆积起来tock:

于 2013-03-27T10:18:33.987 回答
-1

首先,您通常只是在单独的线程中启动这样的循环并用标志控制它。其次,如果要使塞子准确,则必须在启动计时器时保存时间戳,并且每次计时器循环都会显示开始时间戳和当前时间戳之间的差异。示例:[[NSDate 日期] timeIntervalSinceDate:startDate];

于 2013-03-27T10:19:41.510 回答