Jak napisać dispatch po GCD w Swift 3 i 4?
W Swift 2 udało mi się użyć dispatch_after
, aby opóźnić akcję za pomocą grand central dispatch:
var dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC)))
dispatch_after(dispatchTime, dispatch_get_main_queue(), {
// your function here
})
Ale to już nie wydaje się kompilować w Swift 3 (lub 4). Jaki jest preferowany sposób zapisu tego w Swift 3 (przy użyciu nowego API wysyłki)?
11 answers
Składnia jest po prostu:
// to run something in 0.1 seconds
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
// your code here
}
Uwaga, powyższa składnia dodawania seconds
jako Double
wydaje się być źródłem nieporozumień (esp, ponieważ byliśmy przyzwyczajeni do dodawania nsec). Ta składnia "dodaj sekundy jako Double
" działa, ponieważ deadline
jest DispatchTime
, a za kulisami istnieje operator +
, który zajmie Double
i doda tyle sekund do DispatchTime
:
public func +(time: DispatchTime, seconds: Double) -> DispatchTime
Ale jeśli naprawdę chcesz dodać liczbę całkowitą msec, µs lub nsec do DispatchTime
, Możesz również dodać DispatchTimeInterval
do a DispatchTime
. Oznacza to, że możesz zrobić:
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) {
os_log("500 msec seconds later")
}
DispatchQueue.main.asyncAfter(deadline: .now() + .microseconds(1_000_000)) {
os_log("1m μs seconds later")
}
DispatchQueue.main.asyncAfter(deadline: .now() + .nanoseconds(1_500_000_000)) {
os_log("1.5b nsec seconds later")
}
To wszystko bezproblemowo działa dzięki tej oddzielnej metodzie przeciążenia dla operatora +
w klasie DispatchTime
.
public func +(time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTime
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-14 20:42:34
Swift 4:
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) {
// Code
}
Na czas .seconds(Int)
, .microseconds(Int)
i .nanoseconds(Int)
mogą być również używane.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-05 10:08:32
Jeśli chcesz tylko funkcję delay w
Swift 4
func delay(delay: Double, closure: @escaping () -> ()) {
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
closure()
}
}
Możesz go używać w następujący sposób:
delay(delay: 1) {
print("Hi!")
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-04 15:38:27
Po wydaniu Swift 3 należy dodać również @ escaping
func delay(_ delay: Double, closure: @escaping () -> ()) {
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
closure()
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-03 15:40:39
Swift 4
Możesz utworzyć rozszerzenie na DispatchQueue i dodać funkcję delay, która używa DispatchQueue
asyncafter wewnętrznie
extension DispatchQueue {
static func delay(_ delay: DispatchTimeInterval, closure: @escaping () -> ()) {
DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: closure)
}
}
I używać
DispatchQueue.delay(.milliseconds(10)) {
print("task to be done")
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-26 09:32:47
Nieco inny smak zaakceptowanej odpowiedzi.
Swift 4
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1 + .milliseconds(500) +
.microseconds(500) + .nanoseconds(1000)) {
print("Delayed by 0.1 second + 500 milliseconds + 500 microseconds +
1000 nanoseconds)")
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-07 06:53:29
Call DispatchQueue.main.after(when: DispatchTime, execute: () -> Void)
Gorąco polecam korzystanie z narzędzi Xcode do konwersji do Swift 3 (Edycja > Konwertuj > do bieżącej składni Swift). It caught this for me
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-14 01:30:56
To działało dla mnie w Swift 3
let time1 = 8.23
let time2 = 3.42
// Delay 2 seconds
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
print("Sum of times: \(time1 + time2)")
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-30 11:40:48
Możesz użyć
DispatchQueue.main.asyncAfter(deadline: .now() + .microseconds(100)) {
// Code
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-26 11:29:21
Spróbuj tego
let when = DispatchTime.now() + 1.5
DispatchQueue.main.asyncAfter(deadline: when) {
//some code
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-07 12:58:35
W Swift 4.1 i Xcode 9.4.1
Prosta odpowiedź brzmi...
//To call function after 5 seconds time
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
//Here call your function
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-18 06:11:29