स्विफ्ट में जीसीडी मुख्य धागे पर मापदंडों के साथ विधि कैसे कॉल करें?


192

मेरे ऐप में मेरे पास एक फ़ंक्शन है जो एक NSRURLSession बनाता है और एक NSURLRequest का उपयोग करके भेजता है

sesh.dataTaskWithRequest(req, completionHandler: {(data, response, error)

इस कार्य के लिए पूरा होने वाले ब्लॉक में, मुझे कुछ गणना करने की आवश्यकता है जो कॉलिंग व्यू कंट्रौलर में एक UIImage जोड़ता है। मुझे एक फंक कहा जाता है

func displayQRCode(receiveAddr, withAmountInBTC:amountBTC)

यह UIImage- जोड़ गणना करता है। अगर मैं पूर्णता ब्लॉक के अंदर व्यू-एडिंग कोड को चलाने का प्रयास करता हूं, तो Xcode यह कहते हुए एक त्रुटि फेंकता है कि मैं पृष्ठभूमि प्रक्रिया में लेआउट इंजन का उपयोग नहीं कर सकता। इसलिए मैंने SO पर कुछ कोड पाया जो मुख्य थ्रेड पर एक विधि को पंक्तिबद्ध करने की कोशिश करता है:

let time = dispatch_time(DISPATCH_TIME_NOW, Int64(0.0 * Double(NSEC_PER_MSEC)))

dispatch_after(time, dispatch_get_main_queue(), {
    let returned = UIApplication.sharedApplication().sendAction("displayQRCode:", to: self.delegate, from: self, forEvent: nil)
})

हालाँकि, मुझे नहीं पता कि इस फ़ंक्शन कॉल में "ReceAddr" और "amountBTC" पैरामीटर को कैसे जोड़ा जाए। मैं यह कैसे करूंगा, या कोई व्यक्ति एप्लिकेशन के मुख्य कतार में एक विधि कॉल जोड़ने के लिए एक इष्टतम तरीका सुझा सकता है?

जवाबों:


496

स्विफ्ट के आधुनिक संस्करण DispatchQueue.main.asyncमुख्य धागे को भेजने के लिए उपयोग करते हैं :

DispatchQueue.main.async { 
  // your code here
}

करने के लिए के बाद प्रेषण मुख्य कतार, उपयोग पर:

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

स्विफ्ट के पुराने संस्करणों का उपयोग किया गया:

dispatch_async(dispatch_get_main_queue(), {
  let delegateObj = UIApplication.sharedApplication().delegate as YourAppDelegateClass
  delegateObj.addUIImage("yourstring")
})

जब आप सही होते हैं कि आपका सुझाव काम करता है, तो मुझे लगता है कि मेरा उत्तर थोड़ा बेहतर है क्योंकि यह UIApplication.saredApplication पर कॉल नहीं करता है, जो असामान्य है और मेरे कोड के अन्य पाठकों को फेंक सकता है। मेरे उत्तर का दायरा महत्व की वस्तुओं के लिए विवश है, जबकि आपका सहायक वस्तुओं को लाता है, जिससे मुझे यह जानने के लिए अधिक डॉक्स पढ़ने की आवश्यकता होती है कि मैं क्या कर रहा हूं। और मैंने सही फ़ंक्शन कॉल को शामिल करने के लिए अपने मूल प्रश्न को संपादित किया है। मैंने सोचा था कि DisplayQRCode पर्याप्त विशिष्ट नहीं था, लेकिन हमारी टिप्पणियों के साथ अब यह है। यह बात बताने के लिए धन्यवाद।
अलम जूल 28'14

84

स्विफ्ट 3+ और स्विफ्ट 4 संस्करण:

DispatchQueue.main.async {
    print("Hello")
}

स्विफ्ट 3 और एक्सकोड 9.2:

dispatch_async_on_main_queue {
    print("Hello")
}

15

स्विफ्ट 2

ट्रेलिंग क्लोजर का उपयोग करना यह बन जाता है:

dispatch_async(dispatch_get_main_queue()) {
    self.tableView.reloadData()
}

ट्रेलिंग क्लोज़र्स स्विफ्ट सिंटैक्टिक शुगर है जो फ़ंक्शन पैरामीटर स्कोप के बाहर क्लोजर को परिभाषित करने में सक्षम बनाता है। अधिक जानकारी के लिए स्विफ्ट 2.2 प्रोग्रामिंग लैंग्वेज गाइड में ट्रेलिंग क्लोजर देखें ।

Dispatch_async मामले में API func dispatch_async(queue: dispatch_queue_t, _ block: dispatch_block_t)तब dispatch_block_tसे उपनाम के लिए टाइप है () -> Void- एक क्लोजर जो 0 पैरामीटर प्राप्त करता है और जिसमें रिटर्न वैल्यू नहीं है, और फ़ंक्शन के अंतिम पैरामीटर होने के कारण हम बाहरी दायरे में क्लोजर को परिभाषित कर सकते हैं dispatch_async


1
यह ठीक 3 पंक्तियाँ हैं, जो मैं देख रहा हूँ ... अब आप मेरे दिमाग को पढ़ना बंद कर सकते हैं
लेज़्ज़लो


7

यहां दूसरे उत्तर के समान परिणाम प्राप्त करने के लिए अच्छे (IMO) Swifty / कोको शैली वाक्य रचना है:

NSOperationQueue.mainQueue().addOperationWithBlock({
    // Your code here
})

या आप कम कोड और अधिक कार्यक्षमता के लिए लोकप्रिय Async स्विफ्ट लाइब्रेरी को पकड़ सकते हैं :

Async.main {
    // Your code here
}

विधि का नाम बदलकरOperationQueue.main.addOperation({ }
Frostmourne

3

ऐसा करने का उचित तरीका है कि main_queue में dispatch_async का उपयोग किया जाए, जैसा कि मैंने निम्नलिखित कोड में किया था

dispatch_async(dispatch_get_main_queue(), {
    (self.delegate as TBGQRCodeViewController).displayQRCode(receiveAddr, withAmountInBTC:amountBTC)
})

2

यहाँ एक अच्छा सा वैश्विक कार्य है जिसे आप एक अच्छे वाक्यविन्यास के लिए जोड़ सकते हैं:

func dispatch_on_main(block: dispatch_block_t) {
    dispatch_async(dispatch_get_main_queue(), block)
}

और उपयोग

dispatch_on_main {
    // Do some UI stuff
}

2
//Perform some task and update UI immediately.
DispatchQueue.global(qos: .userInitiated).async {  
    // Call your function here
    DispatchQueue.main.async {  
        // Update UI
        self.tableView.reloadData()  
    }
}

//To call or execute function after some time
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
    //Here call your function
}

//If you want to do changes in UI use this
DispatchQueue.main.async(execute: {
    //Update UI
    self.tableView.reloadData()
})

2

यदि आप स्वयं को बंद के अंदर उपयोग कर रहे हैं तो स्वयं को कमजोर करना न भूलें।

dispatch_async(dispatch_get_main_queue(),{ [weak self] () -> () in
    if let strongSelf = self {
        self?.doSomething()
    }
})

1
क्या आप कृपया बता सकते हैं कि हमें ऐसा क्यों करना चाहिए?
जैकस्पेयर

ऐसा इसलिए है क्योंकि यह मेमोरी साइकल बना सकता है - अर्थात मेरे पास किसी चीज का एक मजबूत संदर्भ है और इसका मेरे पास एक मजबूत संदर्भ है। मतलब हममें से कोई भी मेमोरी हीप को नहीं छोड़ सकता।
जैकफॉलकोड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.