2014-12-01 28 views
1

我有經驗,每分鐘運行一次,像的NSTimer每分鐘運行,但與的NSTimer第一第二

NSTimer.scheduledTimerWithTimeInterval(60.0, target: self, selector: Selector("everyMinute"), userInfo: nil, repeats: true) 

是否有可能使用的NSTimer,其他一些類,或其他一些控制,運行一些方法每分鐘但在分鐘的第一秒?

我有一些想法如何實現它在我自己,但我第一次檢查是這個已經存在?

+0

你需要每分鐘的第一秒,而不是僅僅一分鐘一次有什麼特別的原因嗎?只是問,因爲你正在運行的當前設備上的時間不太可能是完全正確的。 – Fogmeister 2014-12-01 15:59:11

+0

我認爲問題是,反正是有,我們可以在正是我們所需要基於設備的時間的時間保證的東西執行。也想親自了解這一點。 – Unheilig 2014-12-01 16:00:54

+0

@Fogmeister我想更新自定義標籤的分鐘數,但希望在+ 2秒內正確。但不想每秒都打電話給NSTimer。我知道這是瘋狂的:-) – WebOrCode 2014-12-01 16:07:40

回答

7

一種方式將是使用NSCalendar找出當前下一分鐘,並安排定時器從該開始,在runLoop

let date = NSDate() 
let calendar = NSCalendar.currentCalendar() 
let components = calendar.components(NSCalendarUnit.CalendarUnitEra|NSCalendarUnit.CalendarUnitYear|NSCalendarUnit.CalendarUnitMonth|NSCalendarUnit.CalendarUnitDay|NSCalendarUnit.CalendarUnitHour|NSCalendarUnit.CalendarUnitMinute, fromDate: date) 
components.minute += 1 
components.second = 1 
let nextMinuteDate = calendar.dateFromComponents(components) 
let timer = NSTimer(fireDate: nextMinuteDate!, interval: 60, target: self, selector: Selector("everyMinute"), userInfo: nil, repeats: true) 
NSRunLoop.mainRunLoop().addTimer(timer, forMode: NSDefaultRunLoopMode) 
+0

我喜歡你的方法,我有同樣的想法,但我的代碼最終會變得更加複雜。 – WebOrCode 2014-12-01 16:34:23

+1

我猜你也可以設置'components.second = 0',我不認爲你真的需要它是第一第二 – 2014-12-01 16:43:35

+1

非常不錯的方式!是的components.second = 0更好。 – LastMove 2014-12-01 16:54:19

1

的的NSDate方法,因爲一月timeIntervalSinceReferenceDate返回的秒數手動調度1,2001,格林威治標準時間上午12:00。它包括的第二

分數如果你調用,除以60,取最低值,然後乘以60,它應該給你目前的「圓分鐘」的時間間隔。將60加到上面,你得到下一個「round minute」的時間間隔,給THAT加1,在下一個「round minute」之後你得到一秒的時間間隔

代碼可能看起來像這樣的:

NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate]; 
NSTimeInterval nextMinute = floor(now/60)*60 + 61 //time interval for next minute, plus 1 second 
NSTimeInterval delay = nextMinute - now; 
//Delay now contains the number of seconds until the next "round minute", plus 1 second. 

dispatch_after(
    dispatch_time(DISPATCH_TIME_NOW, 
    (int64_t)(delay * NSEC_PER_SEC)), 
    dispatch_get_main_queue(),^
    { 
    //Replace the code below with whatever target/userInfo you need. 
    [NSTimer scheduledTimerWithTimeInterval: 60 
     target: self 
     userInfo: nil; 
     repeats: YES]; 
    } 
); 

編輯:其實,一分鐘的「第一第二」是第零秒,所以你應該改變+61在計算nextMinute爲「+60」上面的代碼,而不是「+61」

+0

你的邏輯和法比奧的答案一樣,有一些區別嗎? – WebOrCode 2014-12-01 19:20:24

+0

我的解決方案使用純算術。法比奧需要使用NSCalendar和NSDateComponents。 – 2014-12-01 19:27:54

+0

let delay = 60 - NSDate.timeIntervalSinceReferenceDate()%60 – 2016-05-31 07:22:04

0

The accepted answer,updated for Swift 4:

let date = Date() 
let calendar = Calendar.current 
var components = calendar.dateComponents([.era, .year, .month, .day, .hour, .minute], from: date) 

guard let minute = components.minute else { return } 
components.second = 0 
components.minute = minute + 1 

guard let nextMinute = calendar.date(from: components) else { return } 

let timer = Timer(fire: nextMinute, interval: 60, repeats: true) { [weak self] timer in 
    self?.everyMinute() 
} 
RunLoop.main.add(timer, forMode: .defaultRunLoopMode)