Clark_after - GCD trong Swift?


558

Tôi đã xem qua iBook từ Apple và không thể tìm thấy bất kỳ định nghĩa nào về nó:

Ai đó có thể giải thích cấu trúc của dispatch_after?

dispatch_after(<#when: dispatch_time_t#>, <#queue: dispatch_queue_t?#>, <#block: dispatch_block_t?#>)

1
Apple chưa xuất bản cuốn sách này vào năm 2018. Kho lưu trữ mới nhất tôi có thể tìm thấy là từ tháng 12 năm 2017 . Các liên kết cũ đến iBook giờ chỉ cần chuyển hướng đến developer.apple.com/documentation/swift .
Cœur

Câu trả lời:


742

Một ý tưởng rõ ràng hơn về cấu trúc:

dispatch_after(when: dispatch_time_t, queue: dispatch_queue_t, block: dispatch_block_t?)

dispatch_time_tlà một UInt64. Kiểu dispatch_queue_tthực sự được đặt bí danh cho một NSObject, nhưng bạn chỉ nên sử dụng các phương thức GCD quen thuộc của mình để nhận hàng đợi. Các khối là một đóng cửa Swift. Cụ thể, dispatch_block_tđược định nghĩa là () -> Void, tương đương với () -> ().

Ví dụ sử dụng:

let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC)))
dispatch_after(delayTime, dispatch_get_main_queue()) {
    print("test")
}

BIÊN TẬP:

Tôi khuyên bạn nên sử dụng chức năng thực sự tốt đẹp của @ mattdelay .

EDIT 2:

Trong Swift 3, sẽ có các hàm bao mới cho GCD. Xem tại đây: https://github.com/apple/swift-evolution/blob/master/proposeals/0088-libdispatch-for-swift3.md

Ví dụ ban đầu sẽ được viết như sau trong Swift 3:

let deadlineTime = DispatchTime.now() + .seconds(1)
DispatchQueue.main.asyncAfter(deadline: deadlineTime) {
    print("test")
}

Lưu ý rằng bạn có thể viết deadlineTimekhai báo dưới dạng DispatchTime.now() + 1.0và nhận được kết quả tương tự vì +toán tử bị ghi đè như sau (tương tự cho -):

  • func +(time: DispatchTime, seconds: Double) -> DispatchTime
  • func +(time: DispatchWalltime, interval: DispatchTimeInterval) -> DispatchWalltime

Điều này có nghĩa là nếu bạn không sử dụng DispatchTimeInterval enumvà chỉ viết một số, có thể giả định rằng bạn đang sử dụng giây.


17
Mẹo: Vì khối là tham số cuối cùng của hàm, bạn có thể sử dụng cú pháp "đóng dấu" của Swift để dễ đọc hơn:dispatch_after(1, dispatch_get_main_queue()) { println("test") }
Bill

8
Tôi nghĩ rằng việc sử dụng số 1trong dispatch_after(1, ...có thể gây ra nhiều nhầm lẫn ở đây. Mọi người sẽ nghĩ đó là một vài giây, khi nó thực sự là nano giây . Tôi đề nghị xem câu trả lời của @brindy về cách tạo số này đúng cách.
Hlung

3
Vui lòng thay đổi 1để dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC)))vì nó dẫn đến sự nhầm lẫn. Mọi người có thể nghĩ rằng bạn không cần phải tạo một
Clark_time_t

4
Phiên bản Swift 3 dường như không hoạt động. Nó phàn nàn rằng Binary operator '+' cannot be applied to operands of type DispatchTime and '_'trên đường dâylet delayTime = DispatchTime.now() + .seconds(1.0)
Andy Ibanez

9
Viết lại nó DispatchTime.now() + 1.0dường như là cách duy nhất để làm cho nó hoạt động (không cần .seconds)
Andy Ibanez

1092

Tôi sử dụng dispatch_afterthường xuyên đến nỗi tôi đã viết một hàm tiện ích cấp cao nhất để làm cho cú pháp đơn giản hơn:

func delay(delay:Double, closure:()->()) {
    dispatch_after(
        dispatch_time(
            DISPATCH_TIME_NOW,
            Int64(delay * Double(NSEC_PER_SEC))
        ),
        dispatch_get_main_queue(), closure)
}

Và bây giờ bạn có thể nói như thế này:

delay(0.4) {
    // do stuff
}

Wow, một ngôn ngữ mà bạn có thể cải thiện ngôn ngữ. Những gì có thể tốt hơn?


Cập nhật cho Swift 3, Xcode 8 Seed 6

Có vẻ như không đáng bận tâm, bây giờ họ đã cải thiện cú pháp gọi:

func delay(_ delay:Double, closure:@escaping ()->()) {
    let when = DispatchTime.now() + delay
    DispatchQueue.main.asyncAfter(deadline: when, execute: closure)
}

2
Tôi chỉ cần phím tắt để tính toán độ trễ, kết thúc bằng:func delayInSec(delay: Double) -> dispatch_time_t { return dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC))) }
Aviel Gross

4
@ agf119105 Nếu bạn chỉ có một dòng mã trong bao đóng, hãy thêm một dòng mã khác (ví dụ return).
matt

2
@GastonM Không liên quan. Truyền một chức năng có bản thân nó không có vấn đề quản lý bộ nhớ.
matt

7
"Một ngôn ngữ mà bạn có thể cải thiện ngôn ngữ". Tôi không hiểu cách xác định chức năng toàn cầu đang cải thiện ngôn ngữ hoặc tại sao điều này thậm chí không thể thực hiện được trong C. Có thể nếu bạn quá tải một nhà điều hành;)1.0 ~~ { code...}
Yerk

8
Không đặt câu hỏi về tính chính xác của câu trả lời của bạn nhưng không phải là "Tôi sử dụng công cụ thường xuyên" một mùi mã sẽ được chiến đấu tốt nhất bằng cách không cung cấp chức năng tiện lợi?
Nikolai Ruhe

128

Swift 3+

Điều này cực dễ và thanh lịch trong Swift 3+:

DispatchQueue.main.asyncAfter(deadline: .now() + 4.5) {
    // ...
}

Trả lời cũ hơn:

Để mở rộng câu trả lời của Cezary, sẽ thực hiện sau 1 nano giây, tôi đã phải làm như sau để thực hiện sau 4 giây rưỡi.

let delay = 4.5 * Double(NSEC_PER_SEC)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
dispatch_after(time, dispatch_get_main_queue(), block)

Chỉnh sửa: Tôi phát hiện ra rằng mã ban đầu của tôi là hơi sai. Gõ ngầm định gây ra lỗi biên dịch nếu bạn không chuyển NSEC_PER_SEC thành Double.

Nếu bất cứ ai có thể đề xuất một giải pháp tối ưu hơn, tôi rất muốn nghe nó.


Tôi gặp lỗi trình biên dịch cho API không dùng nữa dispatch_get_current_queue(). Tôi đã sử dụng dispatch_get_main_queue()thay thế.
David L

@DavidL - cảm ơn, dispatch_get_main_queue()chắc chắn là những gì bạn nên sử dụng. Sẽ nâng cấp.
brindy

tôi đã thử điều này trong một sân chơi với swift 3 và nó không hoạt động
μλὼλ

@GAlexander Làm việc cho tôi. Bạn có cho phép sân chơi thực hiện vô thời hạn?
brindy

uhm, không, tôi đã chạy trong vài giờ và vẫn không có gì được in. đây là những gì tôi đã sử dụng. "DispatchQueue.main.asyncAfter nhập khẩu văn nhập khẩu Darwin nhập khẩu CoreGraphics'(Hạn chót: Now () + 4,5) {print (" đến đây ")}"
μολὼν.λαβέ

83

Cú pháp của matt rất hay và nếu bạn cần làm mất hiệu lực khối, bạn có thể muốn sử dụng:

typealias dispatch_cancelable_closure = (cancel : Bool) -> Void

func delay(time:NSTimeInterval, closure:()->Void) ->  dispatch_cancelable_closure? {

    func dispatch_later(clsr:()->Void) {
        dispatch_after(
            dispatch_time(
                DISPATCH_TIME_NOW,
                Int64(time * Double(NSEC_PER_SEC))
            ),
            dispatch_get_main_queue(), clsr)
    }

    var closure:dispatch_block_t? = closure
    var cancelableClosure:dispatch_cancelable_closure?

    let delayedClosure:dispatch_cancelable_closure = { cancel in
        if closure != nil {
            if (cancel == false) {
                dispatch_async(dispatch_get_main_queue(), closure!);
            }
        }
        closure = nil
        cancelableClosure = nil
    }

    cancelableClosure = delayedClosure

    dispatch_later {
        if let delayedClosure = cancelableClosure {
            delayedClosure(cancel: false)
        }
    }

    return cancelableClosure;
}

func cancel_delay(closure:dispatch_cancelable_closure?) {

    if closure != nil {
        closure!(cancel: true)
    }
}

Sử dụng như sau

let retVal = delay(2.0) {
    println("Later")
}
delay(1.0) {
    cancel_delay(retVal)
}

tín dụng

Liên kết ở trên dường như được xuống. Mã Objc gốc từ Github


1
Một tính năng hiệu suất có PerformanceSelector: afterDelay là khả năng hủy bỏ nó. Chỉ có giải pháp này bao gồm các vấn đề. Cảm ơn
HotJard

@HotJard Lưu ý rằng performSelector:afterDelay:hiện đã có trong Swift 2, vì vậy bạn có thể hủy nó.
matt

@matt nhưng nó chỉ có sẵn cho NSObject, phải không?
HotJard

@HotJard Chắc chắn nhưng điều đó tốt hơn là không có nó. Tôi thấy không có vấn đề ở đó. Tuy nhiên, giống như với câu trả lời này, tôi đã bù đắp cho sự mất mát của nó bằng cách viết một bộ đếm thời gian dispatch_source_thủy dựa trên GCD (sử dụng một , vì đó là thứ bạn có thể hủy).
matt

2
Cảm ơn rất nhiều, tôi đã sử dụng tính năng này lên đến Swift 2.3. Trình biên dịch Swift 3.0 hiện đang phàn nàn, sẽ rất tuyệt nếu bạn cập nhật câu trả lời của mình!
độc hại

27

Giải pháp đơn giản nhất trong Swift 3.0 & Swift 4.0 & Swift 5.0

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

Sử dụng

delayWithSeconds(1) {
   //Do something
}

22

Apple có một đoạn công văn sau khi chọn Objective-C :

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<#delayInSeconds#> * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    <#code to be executed after a specified delay#>
});

Đây là đoạn trích tương tự được chuyển sang Swift 3:

DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + <#delayInSeconds#>) {
  <#code to be executed after a specified delay#>
}

14

Một cách khác là mở rộng gấp đôi như thế này:

extension Double {
   var dispatchTime: dispatch_time_t {
       get {
           return dispatch_time(DISPATCH_TIME_NOW,Int64(self * Double(NSEC_PER_SEC)))
       }
   }
}

Sau đó, bạn có thể sử dụng nó như thế này:

dispatch_after(Double(2.0).dispatchTime, dispatch_get_main_queue(), { () -> Void in
            self.dismissViewControllerAnimated(true, completion: nil)
    })

Tôi thích chức năng trì hoãn của matt nhưng không được ưu tiên. Tôi muốn hạn chế việc đóng cửa xung quanh.


8

Trong Swift 3.0

Công văn xếp hàng

  DispatchQueue(label: "test").async {
        //long running Background Task
        for obj in 0...1000 {
            print("async \(obj)")
        }

        // UI update in main queue
        DispatchQueue.main.async(execute: { 
            print("UI update on main queue")
        })

    }

    DispatchQueue(label: "m").sync {
        //long running Background Task
        for obj in 0...1000 {
            print("sync \(obj)")
        }

        // UI update in main queue
        DispatchQueue.main.sync(execute: {
            print("UI update on main queue")
        })
    }

Công văn sau 5 giây

    DispatchQueue.main.after(when: DispatchTime.now() + 5) {
        print("Dispatch after 5 sec")
    }

4

Phiên bản Swift 3.0

Sau chức năng đóng thực thi một số tác vụ sau khi trì hoãn trên luồng chính.

func performAfterDelay(delay : Double, onCompletion: @escaping() -> Void){

    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + delay, execute: {
       onCompletion()
    })
}

Gọi hàm này như sau:

performAfterDelay(delay: 4.0) {
  print("test")
}

4

1) Thêm phương thức này như là một phần của Phần mở rộng UIViewControll.

extension UIViewController{
func runAfterDelay(delay: NSTimeInterval, block: dispatch_block_t) {
        let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)))
        dispatch_after(time, dispatch_get_main_queue(), block)
    }
}

Gọi phương thức này trên VC:

    self.runAfterDelay(5.0, block: {
     //Add code to this block
        print("run After Delay Success")
    })

2)

performSelector("yourMethod Name", withObject: nil, afterDelay: 1)

3)

override func viewWillAppear(animated: Bool) {

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2), dispatch_get_main_queue(), { () -> () in
    //Code Here
})

// Mẫu nhỏ gọn

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2), dispatch_get_main_queue()) {
    //Code here
 }
}

3

Mặc dù không phải là câu hỏi ban đầu của OP, một số NSTimercâu hỏi liên quan đã được đánh dấu là trùng lặp của câu hỏi này, vì vậy nó có giá trị bao gồm một NSTimercâu trả lời ở đây.

NSTimer đấu với dispatch_after

  • NSTimerlà cấp cao hơn trong khi dispatch_aftercấp thấp hơn.
  • NSTimerdễ dàng hơn để hủy bỏ. Hủy bỏ dispatch_afteryêu cầu viết thêm mã .

Trì hoãn một nhiệm vụ với NSTimer

Tạo một NSTimerví dụ.

var timer = NSTimer()

Bắt đầu hẹn giờ với độ trễ mà bạn cần.

// invalidate the timer if there is any chance that it could have been called before
timer.invalidate()
// delay of 2 seconds
timer = NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: #selector(delayedAction), userInfo: nil, repeats: false) 

Thêm một hàm được gọi sau độ trễ (sử dụng bất kỳ tên nào bạn đã sử dụng cho selectortham số ở trên).

func delayedAction() {
    print("Delayed action has now started."
}

Ghi chú

  • Nếu bạn cần hủy hành động trước khi nó xảy ra, chỉ cần gọi timer.invalidate().
  • Đối với một hành động sử dụng lặp đi lặp lại repeats: true.
  • Nếu bạn có một sự kiện một lần mà không cần phải hủy thì không cần phải tạo timerbiến thể hiện. Sau đây sẽ đủ:

    NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: #selector(delayedAction), userInfo: nil, repeats: false) 
  • Xem câu trả lời đầy đủ hơn của tôi ở đây .


3

Đối với nhiều chức năng sử dụng này. Điều này rất hữu ích để sử dụng hình động hoặc Trình tải hoạt động cho các chức năng tĩnh hoặc bất kỳ Cập nhật giao diện người dùng nào.

DispatchQueue.main.asyncAfter(deadline: .now() + 0.9) {
            // Call your function 1
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                // Call your function 2
            }
        }

Ví dụ: Sử dụng hình động trước khi tải lại bảngView. Hoặc bất kỳ cập nhật giao diện người dùng khác sau khi hình ảnh động.

*// Start your amination* 
self.startAnimation()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.9) {
                *// The animation will execute depending on the delay time*
                self.stopAnimation()
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                    *// Now update your view*
                     self.fetchData()
                     self.updateUI()
                }
            }

2

Điều này làm việc cho tôi.

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)")
}

Mục tiêu-C:

CGFloat time1 = 3.49;
CGFloat time2 = 8.13;

// Delay 2 seconds

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    CGFloat newTime = time1 + time2;
    NSLog(@"New time: %f", newTime);
});

2

Swift 3 & 4:

Bạn có thể tạo tiện ích mở rộng trên DispatchQueue và thêm chức năng trì hoãn sử dụng chức năng DispatchQueue asyncAfter trong nội bộ

extension DispatchQueue {
    static func delay(_ delay: DispatchTimeInterval, closure: @escaping () -> ()) {
        let timeInterval = DispatchTime.now() + delay
        DispatchQueue.main.asyncAfter(deadline: timeInterval, execute: closure)
    }
}

sử dụng:

DispatchQueue.delay(.seconds(1)) {
    print("This is after delay")
}

1

Một người trợ giúp khác để trì hoãn mã của bạn là 100% Swift trong sử dụng và tùy chọn cho phép chọn một luồng khác để chạy mã bị trì hoãn của bạn từ:

public func delay(bySeconds seconds: Double, dispatchLevel: DispatchLevel = .main, closure: @escaping () -> Void) {
    let dispatchTime = DispatchTime.now() + seconds
    dispatchLevel.dispatchQueue.asyncAfter(deadline: dispatchTime, execute: closure)
}

public enum DispatchLevel {
    case main, userInteractive, userInitiated, utility, background
    var dispatchQueue: DispatchQueue {
        switch self {
        case .main:                 return DispatchQueue.main
        case .userInteractive:      return DispatchQueue.global(qos: .userInteractive)
        case .userInitiated:        return DispatchQueue.global(qos: .userInitiated)
        case .utility:              return DispatchQueue.global(qos: .utility)
        case .background:           return DispatchQueue.global(qos: .background)
        }
    }
}

Bây giờ bạn chỉ cần trì hoãn mã của mình trên luồng chính như thế này:

delay(bySeconds: 1.5) { 
    // delayed code
}

Nếu bạn muốn trì hoãn mã của mình sang một luồng khác :

delay(bySeconds: 1.5, dispatchLevel: .background) { 
    // delayed code that will run on background thread
}

Nếu bạn thích một Framework cũng có một số tính năng tiện dụng hơn thì hãy kiểm tra HandySwift . Bạn có thể thêm nó vào dự án của mình thông qua Carthage sau đó sử dụng chính xác như trong các ví dụ trên, ví dụ:

import HandySwift    

delay(bySeconds: 1.5) { 
    // delayed code
}

1

Tôi luôn thích sử dụng phần mở rộng thay vì các chức năng miễn phí.

Swift 4

public extension DispatchQueue {

  private class func delay(delay: TimeInterval, closure: @escaping () -> Void) {
    let when = DispatchTime.now() + delay
    DispatchQueue.main.asyncAfter(deadline: when, execute: closure)
  }

  class func performAction(after seconds: TimeInterval, callBack: @escaping (() -> Void) ) {
    DispatchQueue.delay(delay: seconds) {
      callBack()
    }
  }

}

Sử dụng như sau.

DispatchQueue.performAction(after: 0.3) {
  // Code Here
}

1

Trì hoãn cuộc gọi GCD bằng asyncSau khi nhanh chóng

let delayQueue = DispatchQueue(label: "com.theappmaker.in", qos: .userInitiated)
let additionalTime: DispatchTimeInterval = .seconds(2)

Chúng ta có thể trì hoãn dưới dạng ** micro giây , mili giây , nano giây

delayQueue.asyncAfter(deadline: .now() + 0.60) {
    print(Date())
}

delayQueue.asyncAfter(deadline: .now() + additionalTime) {
    print(Date())
}

1

Trong Swift 4

Sử dụng đoạn mã này:

    let delayInSec = 1.0
    DispatchQueue.main.asyncAfter(deadline: .now() + delayInSec) {
       // code here
       print("It works")
    }

Điều này đã có trong các câu trả lời khác (ví dụ như của brindy, hoặc của Raul) ... cùng một cú pháp ...
Eric Aya

1
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    // ...
});

Các dispatch_after(_:_:_:)chức năng có ba thông số:

một sự chậm trễ
một công văn xếp hàng
một khối hoặc đóng cửa

Các dispatch_after(_:_:_:)chức năng gọi khối hay đóng cửa trên hàng đợi công văn được truyền cho hàm sau khi một sự chậm trễ nhất định. Lưu ý rằng độ trễ được tạo bằng dispatch_time(_:_:)hàm. Hãy nhớ điều này bởi vì chúng tôi cũng sử dụng chức năng này trong Swift.

Tôi khuyên bạn nên xem qua hướng dẫn Raywenderlich Dispatch hướng dẫn


1

Trong Swift 5, sử dụng ở bên dưới:

 DispatchQueue.main.asyncAfter(deadline: .now() + 0.2, execute: closure) 

// time gap, specify unit is second
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2)) {
            Singleton.shared().printDate()
        }
// default time gap is second, you can reduce it
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
          // just do it!
    }

0

sử dụng mã này để thực hiện một số tác vụ liên quan đến giao diện người dùng sau 2,0 giây.

            let delay = 2.0
            let delayInNanoSeconds = dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)))
            let mainQueue = dispatch_get_main_queue()

            dispatch_after(delayInNanoSeconds, mainQueue, {

                print("Some UI related task after delay")
            })

Phiên bản Swift 3.0

Sau chức năng đóng thực thi một số tác vụ sau khi trì hoãn trên luồng chính.

func performAfterDelay(delay : Double, onCompletion: @escaping() -> Void){

    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + delay, execute: {
       onCompletion()
    })
}

Gọi hàm này như sau:

performAfterDelay(delay: 4.0) {
  print("test")
}

1
Điều này gần giống với các câu trả lời trước
Daniel Galasko

Có vẻ như câu trả lời này đã được thực hiện vào đầu năm 2016 và cũ hơn ít nhất 6 câu trả lời khác ..
eharo2

0

Bây giờ nhiều hơn đường cú pháp cho các công văn không đồng bộ trong Grand Central Dispatch (GCD) trong Swift.

thêm Podfile

pod 'AsyncSwift'

Sau đó, bạn có thể sử dụng nó như thế này.

let seconds = 3.0
Async.main(after: seconds) {
print("Is called after 3 seconds")
}.background(after: 6.0) {
print("At least 3.0 seconds after previous block, and 6.0 after Async code is called")
}

Apple đã cho chúng tôi tất cả những gì cần thiết để sử dụng GCD trong vài dòng. Tại sao phải bận tâm với pod, không gian làm việc và như vậy? Chỉ cần đọc tài liệu về @escaping và chụp. đủ rồi.
ingconti

0

Swift 4 có một cách khá ngắn để làm điều này:

Timer.scheduledTimer(withTimeInterval: 2, repeats: false) { (timer) in
    // Your stuff here
    print("hello")
}

0

Đây là phiên bản đồng bộ của asyncSfter trong Swift:

let deadline = DispatchTime.now() + .seconds(3)
let semaphore = DispatchSemaphore.init(value: 0)
DispatchQueue.global().asyncAfter(deadline: deadline) {
    dispatchPrecondition(condition: .onQueue(DispatchQueue.global()))
    semaphore.signal()
}

semaphore.wait()

Cùng với một không đồng bộ:

let deadline = DispatchTime.now() + .seconds(3)
DispatchQueue.main.asyncAfter(deadline: deadline) {
    dispatchPrecondition(condition: .onQueue(DispatchQueue.global()))
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.