ios - dispatch_after-तेजी से जीसीडी?




swift grand-central-dispatch (13)

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

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

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

1) इस विधि को UIViewController एक्सटेंशन के हिस्से के रूप में जोड़ें।

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) प्रदर्शन चयनकर्ता ("yourMethod नाम", ऑब्जेक्ट के साथ: शून्य, बाद में: 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
}

}


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

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

आपके कोड में देरी करने के लिए एक अन्य सहायक जो उपयोग में 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
}

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

import HandySwift    

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

एक और तरीका इस तरह डबल विस्तार करना है:

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

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


मैं अक्सर 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)
}

यह मेरे लिए काम किया।

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

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

    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)

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

यदि कोई अधिक इष्टतम समाधान का सुझाव दे सकता है तो मैं इसे सुनना चाहता हूं।

== स्विफ्ट 3 == के लिए अद्यतन करें

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

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

स्विफ्ट 4 में ऐसा करने का एक बहुत ही छोटा तरीका है:

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

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

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

credits

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


तेजी से एसिंक का उपयोग कर जीसीडी कॉल में देरी

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

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

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

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

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

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

प्रयोग

delayWithSeconds(1) {
   //Do something
}

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

मुख्य थ्रेड पर देरी के बाद कुछ कार्य निष्पादन कार्य निष्पादित करें।

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

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

इस फ़ंक्शन को इस तरह कॉल करें:

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






grand-central-dispatch