2017-10-14 134 views
0

我對Timer.scheduledTimer()如果執行比指定的withTimeInterval:需要更多時間觸發代碼塊有疑問。Swift`Timer`在指定的時間間隔之前觸發

在執行完程序段或執行程序段的第一條語句後,是否開始倒計時?

//Logic is to waste the time in the block which will take more than 5 secs to run. 
Timer.scheduledTimer(withTimeInterval: 5, repeats: true){ 
    timer in 
    var sum = 0 
    var count = 0 

    print("START===================================") 
    print(Int64(Date().timeIntervalSince1970 * 1000)) 
    for i in 2..<100000 
    { 
     for j in 2..<10000 
     { 
      sum = i+j 
     } 
    } 

    print(sum) // Ignore this. sum is used here so that compiler might won't be able to remove the loop in the optimisations due to unused variable reason. 
    print(Int64(Date().timeIntervalSince1970 * 1000)) 
    print("END===================================") 
} 

RunLoop.main.run() 

輸出

所以我用下面的代碼測試

START=================================== 
1507965166992 
109998 
1507965173888 
END=================================== 
START=================================== 
1507965176993 
109998 
1507965183890 
END=================================== 
START=================================== 
1507965186989 

當我減去先前循環的結束時間和電流回路的開始時間,我總是在3秒左右。但是我已經指定了5秒。這是爲什麼?

回答

1

的步驟檢查的Timer的文檔。

概述

...

...

計時器不是實時的機制。如果在長時間循環標註期間或運行循環處於 未監控定時器的模式下,發生定時器的觸發時間 ,定時器將不會觸發,直到運行循環檢測到定時器的下一次時間 。因此,計時器觸發的實際時間可能會晚得多。

...

因此,定時器不總是在準確的時間執行你的代碼塊。它在運行循環中安排它。如果有一些重要的線程要執行,那麼你的代碼將被延遲。因此,要保持固定的射擊時間,請查看指定tolerance值。

重複和不重複的計時器

您指定計時器是否重複或創建 時間不重複的比較。一個不重複的定時器觸發一次,然後自動使其自身失效,從而防止定時器再次觸發。相比之下,重複計時器會觸發,然後在同一個運行循環中重新安排自己。重複計時器總是根據預定的開火時間來調度自己,而不是實際的開火時間。例如,如果定時器被安排在特定時間觸發,並且在此之後每隔5秒觸發一次,則即使實際觸發時間被延遲,定時觸發時間也將始終在原始5秒時間間隔上下降 。如果發射時間是迄今爲止推遲它傳遞 一個或多個預定的發射時間時,計時器在該時段只發射一次 ;那麼計時器改期,之後 燒製,在未來的下一個計劃發射時間。

在這裏,它說的是,當第一計時器已啓動,但不是當計時器已經結束倒計時開始。


對於你的第一個問題

是否倒計時塊 或執行後開始射擊時,執行該塊的第一條語句?

答案:都沒有。當第一個定時器啓動時,倒計時開始。


對於您的第二個問題

當我減去先前的環和電流 環的開始時間的結束時間,我總是得到約3秒。但是我已經指定了5秒。爲什麼是 ?

回答

1)。正如我在第一個問題中所說的那樣,在第一個計時器開始後,倒計時開始。

2)。在比較重複和非重複計時器,他們說,如果邏輯佔用的時間比timer中的指定時間多,那麼它在執行塊完成之後以及在指定的時間之後只執行一次代碼。

Timer interval: 5 

Time for block to complete: 8 

Then next code will be executed at: 8 + 2 = 10 secs(as 5 is the interval) 

根據你的代碼的輸出

START=================================== 
1507965166992       <---------+ 
109998           | 
1507965173888          | 
END===================================   | 
START===================================   | 
1507965176993       <---------+ 
109998           | 
1507965183890          | 
END===================================   | 
START===================================   | 
1507965186989       <---------+ 

檢查上面的箭頭標記的時間差。它執行後10secs準確的代碼(其是與​​I相同上面已經給出的解釋)。

提示:經常關注和提問前閱讀文檔。

-1

使用GCD方法https://www.appcoda.com/grand-central-dispatch/其做出比定時器 好得多,如果你想顯示一個接一個,然後按照下面

let queue1 = DispatchQueue(label: "com.appcoda.queue1", qos: DispatchQoS.userInitiated) 
let queue2 = DispatchQueue(label: "com.appcoda.queue2", qos: DispatchQoS.userInitiated) 

queue1.async{ 
    for i in 2..<100000 { 
     queue2.async{ 
      for j in 2..<10000 { 
      sum = i+j 
      } 
     } 
    } 
} 
+0

'Timer'用於在特定的時間或重複與指定時間間隔的執行來執行代碼。 G.C.D用於多線程。你的解決方案與它有什麼關係? – unknownymouse

+0

通過使用GCD我們也可以輕鬆處理函數的執行.. !! –

+0

但是如何?你能提供一段代碼來模擬GCD中的定時器功能嗎? – unknownymouse

相關問題