डिस्पैच_आफ्टर - स्विफ्ट में जीसीडी?


558

मैं Apple से iBook से गुजरा हूँ , और इसकी कोई परिभाषा नहीं पा सका हूँ:

क्या कोई इसकी संरचना समझा सकता है dispatch_after?

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

1
Apple ने इस पुस्तक को 2018 में अप्रकाशित किया। नवीनतम संग्रह जो मुझे मिल सकता है वह दिसंबर 2017 से है । IBook के पुराने लिंक अब केवल developer.apple.com/documentation/swift पर रीडायरेक्ट करते हैं ।
कूर

जवाबों:


742

संरचना का एक स्पष्ट विचार:

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

dispatch_time_tएक है UInt64dispatch_queue_tवास्तव में एक के लिए उपनामित प्रकार है NSObject, लेकिन आप केवल कतारों पाने के लिए अपने परिचित GCD तरीकों का उपयोग करना चाहिए। ब्लॉक एक स्विफ्ट क्लोजर है। विशेष dispatch_block_tरूप से () -> Void, के रूप में परिभाषित किया गया है , जो इसके बराबर है () -> ()

उदाहरण उपयोग:

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

संपादित करें:

मैं @ मैट वास्तव में अच्छा delayकार्य का उपयोग करने की सलाह देता हूं ।

संपादित करें 2:

स्विफ्ट 3 में, जीसीडी के लिए नए रैपर होंगे। यहां देखें: https://github.com/apple/swift-evolution/blob/master/proposals/0088-libdispatch-for-swift3.md

मूल उदाहरण स्विफ्ट 3 में निम्नानुसार लिखा जाएगा:

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

ध्यान दें कि आप के deadlineTimeरूप में घोषणा लिख सकते हैं DispatchTime.now() + 1.0और एक ही परिणाम प्राप्त कर सकते हैं क्योंकि +ऑपरेटर निम्नानुसार (जैसे के लिए -) ओवरराइड किया गया है :

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

इसका मतलब है कि यदि आप उपयोग नहीं करते हैं DispatchTimeInterval enumऔर सिर्फ एक नंबर लिखते हैं, तो यह माना जाता है कि आप सेकंड का उपयोग कर रहे हैं।


17
युक्ति: क्योंकि ब्लॉक फ़ंक्शन का अंतिम पैरामीटर है, आप अतिरिक्त पठनीयता के लिए स्विफ्ट के "ट्रेलिंग क्लोजर" सिंटैक्स का उपयोग कर सकते हैं:dispatch_after(1, dispatch_get_main_queue()) { println("test") }
बिल

8
मैं नंबर का उपयोग कर लगता है 1में dispatch_after(1, ...यहाँ भ्रम का एक बहुत हो सकती है। लोग सोचेंगे कि यह कितने सेकंड का है, जब यह वास्तव में नैनो-सेकंड है । मेरा सुझाव है कि इस संख्या को ठीक से बनाने के तरीके पर @brindy का उत्तर देखें।
११

3
कृपया बदलने 1के लिए dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC)))है, क्योंकि यह भ्रम होता है। लोग सोच सकते हैं कि आपको Swift
OemerA

4
स्विफ्ट 3 संस्करण काम नहीं करता है। यह शिकायत करता है कि Binary operator '+' cannot be applied to operands of type DispatchTime and '_'लाइन परlet delayTime = DispatchTime.now() + .seconds(1.0)
एंडी इबनेज़

9
पुनर्लेखन के रूप में DispatchTime.now() + 1.0लगता है एक ही तरीका है यह काम (कोई जरूरत नहीं करने के लिए होने के लिए .seconds)
एंडी इबानेज

1092

मैं dispatch_afterइतनी बार उपयोग करता हूं कि मैंने सिंटैक्स को सरल बनाने के लिए एक शीर्ष-स्तरीय उपयोगिता फ़ंक्शन लिखा है:

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

और अब आप इस तरह से बात कर सकते हैं:

delay(0.4) {
    // do stuff
}

वाह, एक ऐसी भाषा जहाँ आप भाषा को बेहतर बना सकते हैं। इससे अच्छा क्या हो सकता है?


स्विफ्ट 3, एक्सकोड 8 सीड 6 के लिए अपडेट

लगता है कि लगभग परेशान नहीं है, अब जब उन्होंने कॉलिंग सिंटैक्स में सुधार किया है:

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

2
मुझे बस देरी गणना के लिए शॉर्टकट की आवश्यकता थी, साथ समाप्त हुआ:func delayInSec(delay: Double) -> dispatch_time_t { return dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC))) }
एविएल ग्रोस

4
@ agf119105 यदि आपके पास क्लोजर में कोड की सिर्फ एक लाइन है, तो कोड की दूसरी लाइन (जैसे return) जोड़ें।
मैट

2
@GastonM अप्रासंगिक। किसी फ़ंक्शन को पास करना अपने आप में कोई स्मृति प्रबंधन समस्या नहीं है।
मैट

7
"एक भाषा जहाँ आप भाषा को बेहतर बना सकते हैं"। मुझे समझ नहीं आ रहा है कि वैश्विक फ़ंक्शन को परिभाषित करना भाषा को कैसे बेहतर बना रहा है, या यह सी में भी क्यों नहीं है। हो सकता है कि यदि आप एक ऑपरेटर को ओवरलोड करते हैं;)1.0 ~~ { code...}
यर्क

8
आपके उत्तर की शुद्धता पर सवाल नहीं उठा रहा है - लेकिन "मैं इतनी बार डिस्पैच_का उपयोग नहीं करता हूं" एक कोड गंध है जो एक सुविधा फ़ंक्शन प्रदान नहीं करने से सबसे अच्छा होगा ?
निकोलाई रुहे

127

स्विफ्ट 3+

यह स्विफ्ट 3+ में सुपर-आसान और सुरुचिपूर्ण है:

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

पुराना उत्तर:

सीज़री के उत्तर पर विस्तार करने के लिए, जो 1 नैनोसेकंड के बाद निष्पादित होगा, मुझे 4 और डेढ़ सेकंड के बाद निष्पादित करने के लिए निम्नलिखित करना था।

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)

संपादित करें: मुझे पता चला कि मेरा मूल कोड थोड़ा गलत था। यदि आप NSEC_PER_SEC को किसी डबल में नहीं डालते हैं तो अवैध टाइपिंग एक संकलित त्रुटि का कारण बनता है।

अगर कोई और अधिक इष्टतम समाधान सुझा सकता है तो मैं इसे सुनने के लिए उत्सुक हूं।


मुझे एक अपग्रेड किए गए API के लिए कंपाइलर त्रुटि मिलती है dispatch_get_current_queue()। मैं dispatch_get_main_queue()इसके बजाय इस्तेमाल किया।
डेविड एल

@ डेविड - धन्यवाद, dispatch_get_main_queue()निश्चित रूप से वह है जो आपको उपयोग करना चाहिए। अपडेट करूंगी।
ब्रांडी

मैंने स्विफ्ट 3 के साथ एक खेल के मैदान में यह कोशिश की और यह काम नहीं करता
μολ.ν.λα in

@GAlexander मेरे लिए काम करता है। क्या आप खेल के मैदान को अनिश्चित काल तक निष्पादित करने की अनुमति दे रहे हैं?
brindy

उह, ठीक है, मैं कुछ घंटों के लिए चलाने के लिए और अभी भी कुछ भी नहीं छपी। यहाँ मैं क्या इस्तेमाल किया है। "आयात डिस्पैच आयात डार्विन आयात CoreGraphics 'DispatchQueue.main.asyncAfter (समय सीमा: .now () + 4.5) {प्रिंट (" यहां मिला ")}
μολὼν.λL import

83

मैट का सिंटैक्स बहुत अच्छा है और यदि आपको ब्लॉक को अमान्य करने की आवश्यकता है, तो आप इसका उपयोग करना चाहते हैं:

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

अनुसरण के रूप में उपयोग करें

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

क्रेडिट

ऊपर लिंक नीचे लगता है। जीथब से मूल ओब्जेक्ट कोड


1
एक प्रदर्शन विशेषता जिसमें प्रदर्शनकर्ता होता है: afterDelay इसे रद्द करने की क्षमता रखता है। केवल यह समाधान समस्या को कवर करता है। धन्यवाद
HotJard

@HotJard नोट जो performSelector:afterDelay:अब स्विफ्ट 2 में उपलब्ध है, इसलिए आप इसे रद्द कर सकते हैं।
मैट

@ matt लेकिन यह केवल NSObject के लिए उपलब्ध है, है ना?
हॉटजार्ड

@HotJard ज़रूर लेकिन यह बिल्कुल नहीं होने से बेहतर है। मुझे वहां कोई मुद्दा नजर नहीं आता। हालाँकि, इस उत्तर के रूप में, मैंने पहले ही जीसीडी-आधारित रद्द करने योग्य टाइमर (एक का उपयोग करके dispatch_source_t, क्योंकि वह कुछ है जिसे आप रद्द कर सकते हैं) लिखकर इसके नुकसान की भरपाई की थी ।
मैट

2
बहुत बहुत धन्यवाद, मैं इसे करने के लिए उपयोग कर रहा हूँ 2.3 स्विफ्ट। स्विफ्ट 3.0 कंपाइलर अब शिकायत कर रहा है, अगर आपने अपना जवाब अपडेट किया तो बहुत अच्छा होगा!
nontomatic

27

स्विफ्ट 3.0 और स्विफ्ट 4.0 और स्विफ्ट 5.0 में सबसे सरल समाधान

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

प्रयोग

delayWithSeconds(1) {
   //Do something
}

22

ऑब्जेक्टिव-सी के लिए Apple के पास एक डिस्पैच_आफ्टर स्निपेट है :

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

यहाँ स्विफ्ट 3 के लिए एक ही स्निपेट रखा गया है :

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

14

एक और तरीका यह है कि डबल को इस तरह बढ़ाया जाए:

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

तो आप इसे इस तरह से उपयोग कर सकते हैं:

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

मुझे मैट की देरी फ़ंक्शन पसंद है, लेकिन वरीयता के बाहर मैं बल्कि पास के क्लोजर को सीमित करना चाहता हूं।


8

स्विफ्ट 3.0 में

डिस्पैच कतारों

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

5 सेकंड के बाद डिस्पैच करें

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

4

स्विफ्ट 3.0 संस्करण

मुख्य थ्रेड पर देरी के बाद क्लोजर फ़ंक्शन कुछ कार्य निष्पादित करता है।

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

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

इस समारोह की तरह कॉल करें:

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

4

1) इस विधि को 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)
    }
}

इस तरीके को वीसी पर कॉल करें:

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

// कॉम्पैक्ट फॉर्म

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

3

हालांकि ओपी द्वारा मूल प्रश्न नहीं, कुछ NSTimerसंबंधित प्रश्नों को इस प्रश्न के डुप्लिकेट के रूप में चिह्नित किया गया है, इसलिए यह NSTimerयहां एक उत्तर सहित लायक है।

NSTimer बनाम dispatch_after

  • NSTimerअधिक उच्च स्तर है जबकि dispatch_afterअधिक निम्न स्तर है।
  • NSTimerरद्द करना आसान है। रद्द करने के dispatch_afterलिए अधिक कोड लिखना आवश्यक है ।

किसी कार्य में देरी करना NSTimer

एक NSTimerउदाहरण बनाएँ ।

var timer = NSTimer()

टाइमर को उस देरी से शुरू करें जिसकी आपको आवश्यकता है।

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

देरी के बाद बुलाया जाने वाला फ़ंक्शन जोड़ें ( selectorऊपर दिए गए पैरामीटर के लिए जो भी नाम आपने उपयोग किया है)।

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

टिप्पणियाँ

  • यदि आपको ऐसा होने से पहले कार्रवाई को रद्द करने की आवश्यकता है, तो बस कॉल करें timer.invalidate()
  • एक दोहराया कार्रवाई का उपयोग करने के लिए repeats: true
  • यदि आपके पास एक समय की घटना है जिसे रद्द करने की आवश्यकता नहीं है, तो timerउदाहरण चर बनाने की कोई आवश्यकता नहीं है । निम्नलिखित पर्याप्त होगा:

    NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: #selector(delayedAction), userInfo: nil, repeats: false) 
  • मेरा फुलर जवाब यहां देखें ।


3

कई कार्यों के लिए इस का उपयोग करें। यह स्थिर कार्यों या किसी भी UI अपडेट के लिए एनिमेशन या गतिविधि लोडर का उपयोग करने के लिए बहुत सहायक है।

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

उदाहरण के लिए - टेबल व्यू रीलोड से पहले एक एनीमेशन का उपयोग करें। या एनीमेशन के बाद कोई अन्य यूआई अपडेट।

*// 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

इसने मेरे लिए काम किया।

स्विफ्ट 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)")
}

उद्देश्य सी:

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

स्विफ्ट 3 और 4:

आप DispatchQueue पर एक एक्सटेंशन बना सकते हैं और फ़ंक्शन विलंब जोड़ सकते हैं जो DispatchQueue asyncAfter का उपयोग करके आंतरिक रूप से कार्य करता है

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

उपयोग:

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

1

आपके कोड में देरी के लिए एक और सहायक जो 100% स्विफ्ट उपयोग में है और वैकल्पिक रूप से आपके विलंबित कोड को चलाने के लिए एक अलग धागा चुनने की अनुमति देता है:

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

अब आप इस तरह से मुख्य धागे पर अपना कोड विलंबित करते हैं :

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

यदि आप अपने कोड को अलग थ्रेड में देरी करना चाहते हैं :

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

यदि आप एक ऐसी फ्रेमवर्क पसंद करते हैं, जिसमें कुछ अधिक उपयोगी विशेषताएं हैं तो हैंडवाइस लिफ्ट चेकआउट करें । आप इसे Carthage के माध्यम से अपनी परियोजना में जोड़ सकते हैं, फिर इसे ऊपर दिए गए उदाहरणों की तरह उपयोग कर सकते हैं, जैसे:

import HandySwift    

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

1

मैं हमेशा मुफ्त कार्यों के बजाय एक्सटेंशन का उपयोग करना पसंद करता हूं।

स्विफ्ट 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()
    }
  }

}

अनुसरण के रूप में उपयोग करें।

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

1

विलंबित GCD कॉल का उपयोग तेज में asyncAfter का उपयोग कर

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

हम ** माइक्रोसेकंड , मिलीसेकंड , नैनोसेकंड के रूप में देरी कर सकते हैं

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

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

1

में स्विफ्ट 4

इस स्निपेट का उपयोग करें:

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

यह पहले से ही अन्य उत्तरों में है (उदाहरण के लिए, या राहुल की) ... समान वाक्य-विन्यास ...
एरिक आया

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

dispatch_after(_:_:_:)समारोह तीन पैरामीटर लेता है:

एक
प्रेषण एक देरी एक
ब्लॉक या बंद कतार

dispatch_after(_:_:_:)समारोह ब्लॉक या प्रेषण कतार है कि किसी भी देरी के बाद समारोह को पारित कर दिया है पर बंद का आह्वान। ध्यान दें कि dispatch_time(_:_:)फ़ंक्शन का उपयोग करके देरी बनाई गई है । इसे याद रखें क्योंकि हम स्विफ्ट में भी इस फ़ंक्शन का उपयोग करते हैं।

मैं ट्यूटोरियल रेवेंडरलिच डिस्पैच ट्यूटोरियल के माध्यम से जाने की सलाह देता हूं


1

स्विफ्ट 5 में, नीचे में उपयोग करें:

 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

2.0 सेकंड के बाद UI से संबंधित कार्य करने के लिए इस कोड का उपयोग करें।

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

स्विफ्ट 3.0 संस्करण

मुख्य थ्रेड पर देरी के बाद क्लोजर फ़ंक्शन कुछ कार्य निष्पादित करता है।

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

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

इस समारोह की तरह कॉल करें:

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

1
यह पिछले उत्तरों के लगभग समान है
डैनियल गैलास्को

ऐसा लगता है कि यह उत्तर 2016 की शुरुआत में किया गया था, और कम से कम अन्य 6 उत्तरों से पुराना है ..
eharo2

0

अब स्विफ्ट में ग्रैंड सेंट्रल डिस्पैच (जीसीडी) में एसिंक्रोनस डिस्पैच के लिए सिंटैक्टिक शुगर से अधिक है।

पॉडफाइल जोड़ें

pod 'AsyncSwift'

फिर, आप इसे इस तरह से उपयोग कर सकते हैं।

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 ने हम सभी को कुछ लाइनों में GCD का उपयोग करने की आवश्यकता दी है। फली, कार्यक्षेत्र इत्यादि से परेशान क्यों? बस @ एस्कॉर्टिंग और कैप्चरिंग के बारे में डॉक्स पढ़ें। यह पर्याप्त है।
21


0

यहाँ स्विफ्ट में asyncAfter का तुल्यकालिक संस्करण है:

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

अतुल्यकालिक एक के साथ:

let deadline = DispatchTime.now() + .seconds(3)
DispatchQueue.main.asyncAfter(deadline: deadline) {
    dispatchPrecondition(condition: .onQueue(DispatchQueue.global()))
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.