Swift 3'te bir gecikme nasıl programlanır


330

Swift'in önceki sürümlerinde, aşağıdaki kodla bir gecikme oluşturulabilir:

let time = dispatch_time(dispatch_time_t(DISPATCH_TIME_NOW), 4 * Int64(NSEC_PER_SEC))
dispatch_after(time, dispatch_get_main_queue()) {
    //put your code which should be executed with a delay here
}

Ama şimdi, Swift 3'te Xcode otomatik olarak 6 farklı şeyi değiştiriyor, ancak aşağıdaki hata ortaya çıkıyor: " aka DispatchTime.nowbeklenen değere dönüştürülemiyor ."dispatch_time_tUInt64

Swift 3'te bir kod dizisi çalıştırmadan önce nasıl gecikme yaşanabilir?

Yanıtlar:


966

Bir çok araştırmadan sonra, sonunda bunu anladım.

DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { // Change `2.0` to the desired number of seconds.
   // Code you want to be delayed
}

Bu, Swift 3 ve Swift 4'te istenen "bekleme" efektini yaratır.

Bu cevabın bir kısmından esinlenildi .


7
Yararlı katkı, teşekkürler! En son Swift 3 için güncelleme:DispatchQueue.main.asyncAfter(deadline: when)
Rogare

77
"+ 2" yerine "+ .seconds (2)" yazarak kodunuzu biraz daha değişken hale getirebilirsiniz. Veya, en üst düzeyde hızlılık için, ilk satırı bırakabilir ve "son tarih:" ile "son tarih: .now () + .seconds (2)" değerini değiştirebilirsiniz.
RenniePet

2
@ OctavioAntonioCedeño Yardım etmekten mutluluk duyarız. Bu beni bir süre rahatsız etti: D
owlswipe

5
Hala çalışıyor 3/12/2017. Bunun için çok teşekkür ederim :)
John Leonardo

3
Kelimenin tam anlamıyla SO en çok ziyaret ettiğim yazı. Aslında bu hatırlamak veya benim
kodumda

154

GCD için tek satırlık gösterimi seviyorum, daha zarif:

    DispatchQueue.main.asyncAfter(deadline: .now() + 42.0) {
        // do stuff 42 seconds later
    }

Ayrıca, iOS 10'da yeni Zamanlayıcı yöntemlerimiz var, örn. Blok başlatıcı:

(bu nedenle gecikmeli işlem iptal edilebilir)

    let timer = Timer.scheduledTimer(withTimeInterval: 42.0, repeats: false) { (timer) in
        // do stuff 42 seconds later
    }

Btw, unutmayın: varsayılan olarak, zamanlayıcı varsayılan çalıştırma döngü moduna eklenir. Bu, kullanıcı uygulamanızın kullanıcı arayüzüyle etkileşime girdiğinde (örneğin, bir UIScrollView kaydırırken) zamanlayıcının donmuş olabileceği anlamına gelir.Zamanlayıcıyı belirli çalışma döngüsü moduna ekleyerek bu sorunu çözebilirsiniz:

RunLoop.current.add(timer, forMode: .common)

Bu blog yazısında daha fazla ayrıntı bulabilirsiniz.


4
İyi yakalama! Henüz görmedim.
julien_c

8
artı Timer karşılaştırması ve ana runloop hakkındaki feragatname için bir tane!
Martin

2
İyi yakaladın! Bu mühendislik.
Onur Şahindur

56

Swift 3.0 ve sonraki sürümlerde uygulanan aşağıdaki işlevi deneyin

func delayWithSeconds(_ seconds: Double, completion: @escaping () -> ()) {
    DispatchQueue.main.asyncAfter(deadline: .now() + seconds) { 
        completion()
    }
}

kullanım

delayWithSeconds(1) {
   //Do something
}

5
Temel olarak bu cevabı kopyaladın ama evet bu iyi, teşekkürler.
owlswipe

2
Bunu nasıl iptal edebilirim?
Sourav Chandra

24

Gecikme için aşağıdaki kodu deneyin

//MARK: First Way

func delayForWork() {
    delay(3.0) {
        print("delay for 3.0 second")
    }
}

delayForWork()

// MARK: Second Way

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
    // your code here delayed by 0.5 seconds
}

1
İlk yol göstergelerinde "Çözümlenmeyen tanımlayıcı" gecikme "kullanımı hatası var
Jerry Chong

5
Bu programcı kod tabanında yardımcı bir yöntemle çalışıyor ve uzun süredir var. Dolayısıyla gecikme, Apple'ın SDK'sından ayrı olmadığını bilmeden bir süredir kullandığı koddu.
Nick Perkins

4

Bunun bir yolu, DispatchQueue.main.asyncAfterbirçok insanın cevapladığı gibi kullanmaktır .

Başka bir yol kullanmaktır perform(_:with:afterDelay:). Daha fazla ayrıntı burada

perform(#selector(delayedFunc), with: nil, afterDelay: 3)

@IBAction func delayedFunc() {
    // implement code
}

1

// x saniye sonra işlevi çalıştırır

public static func runThisAfterDelay(seconds: Double, after: @escaping () -> Void) {
    runThisAfterDelay(seconds: seconds, queue: DispatchQueue.main, after: after)
}

public static func runThisAfterDelay(seconds: Double, queue: DispatchQueue, after: @escaping () -> Void) {
    let time = DispatchTime.now() + Double(Int64(seconds * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)
    queue.asyncAfter(deadline: time, execute: after)
}

// Kullanım: -

runThisAfterDelay(seconds: x){
  //write your code here
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.