ios - मैं स्विफ्ट 3, 4 और 5 में जीसीडी कैसे भेजूं?




swift swift4 (9)

स्विफ्ट 2 में, मैं भव्य केंद्रीय प्रेषण का उपयोग करके कार्रवाई में देरी करने के लिए dispatch_after का उपयोग करने में सक्षम था:

var dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC))) 
dispatch_after(dispatchTime, dispatch_get_main_queue(), { 
    // your function here 
})

लेकिन यह स्विफ्ट 3 के बाद से संकलित नहीं लगता है। आधुनिक स्विफ्ट में इसे लिखने का पसंदीदा तरीका क्या है?


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

DispatchQueue.main.asyncAfter(deadline: .now() + .microseconds(100)) {
        // Code
    }

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

उत्तर में से कोई भी गैर-मुख्य धागे पर चलने का उल्लेख नहीं करता है, इसलिए मेरे 2 सेंट जोड़ रहा है।

मुख्य कतार पर (मुख्य धागा)

let mainQueue = DispatchQueue.main
let deadline = DispatchTime.now() + .seconds(10)
mainQueue.asyncAfter(deadline: deadline) {
    // ...
}

या

DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + .seconds(10)) { 
    // ...
}

वैश्विक कतार पर (गैर मुख्य धागा, QOS पर आधारित)।

let backgroundQueue = DispatchQueue.global()
let deadline = DispatchTime.now() + .milliseconds(100)
backgroundQueue.asyncAfter(deadline: deadline, qos: .background) { 
    // ...
}

या

DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + .milliseconds(100), qos: .background) {
    // ...
}

कॉल करें DispatchQueue.main.after(when: DispatchTime, execute: () -> Void) करें DispatchQueue.main.after(when: DispatchTime, execute: () -> Void)

मैं अत्यधिक 3 स्विफ्ट 3 का उपयोग करने के लिए Xcode टूल का उपयोग करने की सलाह दूंगा (संपादित करें> कन्वर्ट> वर्तमान स्विफ्ट सिंटैक्स में)। इसने मेरे लिए यह पकड़ लिया


वाक्य विन्यास बस है:

// to run something in 0.1 seconds

DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
    // your code here
}

ध्यान दें, Double रूप में seconds जोड़ने के उपरोक्त वाक्यविन्यास भ्रम का कारण लगता है (क्योंकि हम nsec जोड़ने के आदी थे)। यह "सेकंड को Double रूप में जोड़ता है" सिंटैक्स काम करता है क्योंकि deadline एक DispatchTime और, पर्दे के पीछे एक + ऑपरेटर होता है जो एक Double ले जाएगा और DispatchTime कई सेकंड जोड़ देगा:

public func +(time: DispatchTime, seconds: Double) -> DispatchTime

लेकिन, यदि आप वास्तव में DispatchTime को msec, μs या nsec का पूर्णांक संख्या जोड़ना चाहते हैं, तो आप DispatchTimeInterval में एक DispatchTime भी जोड़ सकते हैं। इसका मतलब है कि आप कर सकते हैं:

DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) {
    os_log("500 msec seconds later")
}

DispatchQueue.main.asyncAfter(deadline: .now() + .microseconds(1_000_000)) {
    os_log("1m μs seconds later")
}

DispatchQueue.main.asyncAfter(deadline: .now() + .nanoseconds(1_500_000_000)) {
    os_log("1.5b nsec seconds later")
}

DispatchTime वर्ग में + ऑपरेटर के लिए इस अलग अधिभार विधि के कारण ये सभी मूल रूप से काम करते हैं।

public func +(time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTime

यह पूछा गया कि एक डिस्पैच किए गए कार्य को रद्द करने के बारे में कैसे जाना जाता है। ऐसा करने के लिए, DispatchWorkItem उपयोग करें। उदाहरण के लिए, यह एक कार्य शुरू करता है जो पाँच सेकंड में आग लगा देगा, या यदि दृश्य नियंत्रक को खारिज कर दिया जाता है और deinit किया जाता है, तो इसका कार्य कार्य रद्द कर देगा:

class ViewController: UIViewController {

    private var item: DispatchWorkItem?

    override func viewDidLoad() {
        super.viewDidLoad()

        item = DispatchWorkItem { [weak self] in
            self?.doSomething()
            self?.item = nil
        }

        DispatchQueue.main.asyncAfter(deadline: .now() + 5, execute: item!)
    }

    deinit {
        item?.cancel()
    }

    func doSomething() { ... }

}

DispatchWorkItem में [weak self] कैप्चर सूची के उपयोग पर ध्यान दें। एक मजबूत संदर्भ चक्र से बचने के लिए यह आवश्यक है। यह भी ध्यान दें कि यह एक पूर्व-निरस्तीकरण नहीं करता है, बल्कि कार्य को शुरू करने से रोकता है यदि यह पहले से ही नहीं है। लेकिन अगर यह पहले से ही cancel() कॉल का सामना cancel() के समय से शुरू हो गया है, तो ब्लॉक अपने निष्पादन को समाप्त कर देगा (जब तक कि आप मैन्युअल रूप से चेक नहीं कर रहे हैं ब्लॉक के अंदर रद्द हो जाता है)।


स्विफ्ट 3 रिलीज के बाद, @ फेसिंग को भी जोड़ा जाना है

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

स्वीकृत उत्तर का कुछ अलग स्वाद।

स्विफ्ट 4

DispatchQueue.main.asyncAfter(deadline: .now() + 0.1 + .milliseconds(500) + 
.microseconds(500) + .nanoseconds(1000)) {
                print("Delayed by 0.1 second + 500 milliseconds + 500 microseconds + 
                      1000 nanoseconds)")
 }

स्विफ्ट 4

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

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

और उपयोग करें

DispatchQueue.delay(.milliseconds(10)) {
   print("task to be done")
}

स्विफ्ट 5 और उससे ऊपर

DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: {
   // code to execute                 
})




swift5