dispatch_after - GCD in Swift?

前端 未结 25 2380
心在旅途
心在旅途 2020-11-21 06:07

I\'ve gone through the iBook from Apple, and couldn\'t find any definition of it:

Can someone explain the structure of dispatch_after?

d         


        
相关标签:
25条回答
  • 2020-11-21 06:24

    A clearer idea of the structure:

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

    dispatch_time_t is a UInt64. The dispatch_queue_t is actually type aliased to an NSObject, but you should just use your familiar GCD methods to get queues. The block is a Swift closure. Specifically, dispatch_block_t is defined as () -> Void, which is equivalent to () -> ().

    Example usage:

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

    EDIT:

    I recommend using @matt's really nice delay function.

    EDIT 2:

    In Swift 3, there will be new wrappers for GCD. See here: https://github.com/apple/swift-evolution/blob/master/proposals/0088-libdispatch-for-swift3.md

    The original example would be written as follows in Swift 3:

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

    Note that you can write the deadlineTime declaration as DispatchTime.now() + 1.0 and get the same result because the + operator is overridden as follows (similarly for -):

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

    This means that if you don't use the DispatchTimeInterval enum and just write a number, it is assumed that you are using seconds.

    0 讨论(0)
  • 2020-11-21 06:24

    1) Add this method as a part of UIViewController Extension.

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

    Call this method on 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
    })
    

    //Compact Form

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2), dispatch_get_main_queue()) {
        //Code here
     }
    }
    
    0 讨论(0)
  • 2020-11-21 06:24

    Delaying GCD call using asyncAfter in swift

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

    We can delay as **microseconds,milliseconds,nanoseconds

    delayQueue.asyncAfter(deadline: .now() + 0.60) {
        print(Date())
    }
    
    delayQueue.asyncAfter(deadline: .now() + additionalTime) {
        print(Date())
    }
    
    0 讨论(0)
  • 2020-11-21 06:25

    In Swift 5, use in the below:

     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 讨论(0)
  • 2020-11-21 06:27

    Swift 3 & 4:

    You can create a extension on DispatchQueue and add function delay which uses DispatchQueue asyncAfter function internally

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

    use:

    DispatchQueue.delay(.seconds(1)) {
        print("This is after delay")
    }
    
    0 讨论(0)
  • 2020-11-21 06:31

    Another helper to delay your code that is 100% Swift in usage and optionally allows for choosing a different thread to run your delayed code from:

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

    Now you simply delay your code on the Main thread like this:

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

    If you want to delay your code to a different thread:

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

    If you prefer a Framework that also has some more handy features then checkout HandySwift. You can add it to your project via Carthage then use it exactly like in the examples above, e.g.:

    import HandySwift    
    
    delay(bySeconds: 1.5) { 
        // delayed code
    }
    
    0 讨论(0)
提交回复
热议问题