2013-03-27 32 views
0

我正在學習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]; 
} 
+0

當您在hitti之間等待2秒時,您是否看到該行爲ng停止,然後再次啓動?看起來你至少還會在碰到停止點後排隊等待,這會在1秒後觸發,導致步驟開始,然後啓動過程。如果你在不到一秒的時間點擊開始,你將在隊列中有2個,並且他們將分別射擊並單獨重生。 – gaige 2013-03-27 10:05:53

+0

http://stackoverflow.com/questions/6873627/how-to-implment-laps-in-stop-watch-iphone-app – 2013-03-27 10:33:18

+0

我認爲你是對的。看起來就像它排隊......直接恢復後你很快看到閃爍的缺失數字..幾秒鐘後,你看到每個數字,但intervall更短...我如何需要更改代碼?是的,我知道你可以做不同的事情,但我想知道這種方式的缺陷..我仍然在學習 – Korg 2013-03-27 10:33:42

回答

0

步驟1:聲明以下在h文件兩個變量

NSTimer *secondTimer; 
int seconds; 

步驟2:然後,在

- (void)viewDidLoad 
{ 
    seconds = 0; 
} 

步驟3初始化第二至0:寫爲以下方法和assing 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]]; 
} 
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; 
} 
+0

請編輯這個人。我無法編輯 – user2031994 2013-03-27 10:18:37

0

您需要取消performSelector:withObject:afterDelay:來電。否則,每次撥打電話tock:時,他們都會累積起來。

+0

我如何取消他們? – Korg 2013-03-27 10:38:14

+0

根據文檔,+ [NSObject cancelPreviousPerformRequestsWithTarget:selector:object:] – zadr 2013-03-27 22:57:13

-1

首先,你通常只是在單獨的線程中啓動這樣的循環,並用標誌來控制它。第二,如果你想讓塞子準確無誤,你必須在啓動計時器時以及每次計時器循環顯示開始時間戳和當前時間戳之間的差異時保存一個時間戳。示例: [[NSDate date] timeIntervalSinceDate:startDate];

+0

爲什麼我得到-1? – 2013-03-27 10:39:37