खोज…


वाक्य - विन्यास

  • स्विफ्ट 3.0

  • DispatchQueue.main // मुख्य कतार प्राप्त करें

  • DispatchQueue (लेबल: "my-serial-queue", विशेषताएँ: [.serial, .qosBackground]) // अपनी निजी सीरियल कतार बनाएँ

  • DispatchQueue.global (विशेषताएं: [.qosDefault]) // वैश्विक समवर्ती कतारों में से एक पर पहुंचें

  • DispatchQueue.main.async {...} // कार्य को मुख्य धागे पर अतुल्य रूप से भेजना

  • DispatchQueue.main.sync {...} // किसी कार्य को मुख्य सूत्र में सिंक्रोनाइज़ करें

  • DispatchQueue.main.asyncAfter (समय सीमा: .now () + 3) {...} // एक्स के बाद निष्पादित होने के लिए मुख्य कार्य के लिए असिंक्रोनस रूप से किसी कार्य को डिस्पैच करें

  • स्विफ्ट <3.0

  • dispatch_get_main_queue () // मुख्य धागे पर चल रही मुख्य कतार प्राप्त करें

  • dispatch_get_global_queue (dispatch_queue_priority_t, 0) // निर्दिष्ट प्राथमिकता के साथ वैश्विक कतार प्राप्त करें dispatch_queue_priority_t

  • dispatch_async (dispatch_queue_t) {() -> शून्य में ...} // निर्दिष्ट डिस्पैच_queue_t पर एसिंक्रोनस रूप से कार्य को डिस्पैच करें

  • dispatch_sync (dispatch_queue_t) {() -> शून्य में ...} // निर्दिष्ट डिस्पैच_queue_t पर एक कार्य को सिंक्रोनाइज़ करें

  • dispatch_after (डिस्पैच_टाइम (DISPATCH_TIME_NOW, Int64 (नैनोसेकंड)), dispatch_queue_t, {...}); // नैनोसेकंड्स के बाद निर्दिष्ट प्रेषण_चेक_ टी पर एक कार्य को भेजें

ग्रांड सेंट्रल डिस्पैच (GCD) कतार प्राप्त करना

ग्रांड सेंट्रल डिस्पैच "डिस्पैच क्युस" की अवधारणा पर काम करता है। प्रेषण कतार आपके द्वारा निर्दिष्ट किए गए कार्यों को निष्पादित करती है, जो वे पारित किए जाते हैं। प्रेषण कतारों के तीन प्रकार हैं:

  • सीरियल डिस्पैच क्यू (उर्फ निजी प्रेषण कतार) एक बार में एक कार्य को क्रम में निष्पादित करता है। वे अक्सर एक संसाधन तक पहुंच को सिंक्रनाइज़ करने के लिए उपयोग किए जाते हैं।
  • समवर्ती डिस्पैच क्यू (उर्फ वैश्विक प्रेषण कतार) एक या एक से अधिक कार्यों को समवर्ती रूप से निष्पादित करते हैं।
  • मुख्य डिस्पैच क्यू मुख्य धागे पर कार्यों को निष्पादित करता है।

मुख्य कतार तक पहुँचने के लिए:

3.0
let mainQueue = DispatchQueue.main
3.0
let mainQueue = dispatch_get_main_queue()

प्रणाली अलग-अलग प्राथमिकताओं के साथ समवर्ती वैश्विक प्रेषण कतार (आपके आवेदन के लिए वैश्विक) प्रदान करती है। आप स्विफ्ट 3 में DispatchQueue वर्ग का उपयोग करके इन कतारों तक पहुँच सकते हैं:

3.0
let globalConcurrentQueue = DispatchQueue.global(qos: .default)

के बराबर

let globalConcurrentQueue = DispatchQueue.global()
3.0
let globalConcurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)

आईओएस 8 या बाद में, सेवा मूल्यों की संभावित गुणवत्ता जो पारित की जा सकती है। .userInteractive , .userInitiated , .default , .utility और .background । ये DISPATCH_QUEUE_PRIORITY_ स्थिरांक को प्रतिस्थापित करते हैं।

आप अलग-अलग प्राथमिकताओं के साथ अपनी खुद की कतार भी बना सकते हैं:

3.0
let myConcurrentQueue = DispatchQueue(label: "my-concurrent-queue", qos: .userInitiated, attributes: [.concurrent], autoreleaseFrequency: .workItem, target: nil)
let mySerialQueue = DispatchQueue(label: "my-serial-queue", qos: .background, attributes: [], autoreleaseFrequency: .workItem, target: nil)
3.0
let myConcurrentQueue = dispatch_queue_create("my-concurrent-queue", DISPATCH_QUEUE_CONCURRENT)
let mySerialQueue = dispatch_queue_create("my-serial-queue", DISPATCH_QUEUE_SERIAL)

स्विफ्ट 3 में, इस .workItem के साथ बनाई गई कतारें डिफ़ॉल्ट रूप से धारावाहिक हैं, और गुजरता है। .workItem आवृत्ति के लिए। .workItem यह सुनिश्चित करता है कि प्रत्येक कार्य आइटम के लिए .workItem पूल बनाया और सूखा हो। वहाँ भी है .never जिसका मतलब है कि आप अपने आप को अपने स्वयं के autorelease पूल प्रबंध किया जाएगा, या, .inherit जो वातावरण से सेटिंग को इनहेरिट करती। ज्यादातर मामलों में आप शायद का उपयोग नहीं होगा .never चरम अनुकूलन के मामलों को छोड़कर।

ग्रैंड सेंट्रल डिस्पैच (जीसीडी) कतार में चल रहे कार्य

3.0

एक प्रेषण कतार पर कार्यों को चलाने के लिए, sync , async और तरीकों के after उपयोग करें।

एक कार्य को असंगत रूप से एक कतार में भेजने के लिए:

let queue = DispatchQueue(label: "myQueueName")

queue.async {
    //do something
    
    DispatchQueue.main.async {
        //this will be called in main thread
        //any UI updates should be placed here
    }
}
// ... code here will execute immediately, before the task finished

किसी कार्य को पंक्तिबद्ध तरीके से भेजने के लिए:

queue.sync {
    // Do some task
}
// ... code here will not execute until the task is finished

कुछ सेकंड के बाद किसी कार्य को एक कतार में भेजने के लिए:

queue.asyncAfter(deadline: .now() + 3) {
    //this will be executed in a background-thread after 3 seconds
}
// ... code here will execute immediately, before the task finished

नोट: उपयोगकर्ता-इंटरफ़ेस के किसी भी अपडेट को मुख्य धागे पर बुलाया जाना चाहिए! सुनिश्चित करें, कि आपने UI अपडेट के लिए कोड DispatchQueue.main.async { ... } अंदर डाल दिया है

2.0

कतार के प्रकार:

let mainQueue = dispatch_get_main_queue()
let highQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)
let backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)

एक कार्य को असंगत रूप से एक कतार में भेजने के लिए:

dispatch_async(queue) {
    // Your code run run asynchronously. Code is queued and executed 
    // at some point in the future.
}
// Code after the async block will execute immediately

किसी कार्य को पंक्तिबद्ध तरीके से भेजने के लिए:

dispatch_sync(queue) {
    // Your sync code
}
// Code after the sync block will wait until the sync task finished

एक समय अंतराल के बाद किसी कार्य को भेजने के लिए ( NSEC_PER_SEC का उपयोग कर सेकंड को नैनोसेकंड में परिवर्तित करें):

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(2.5 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) {
    // Code to be performed in 2.5 seconds here
}

एसिंक्रोनस रूप से किसी कार्य को निष्पादित करने के लिए और UI अपडेट करने के लिए:

dispatch_async(queue) {
    // Your time consuming code here
    dispatch_async(dispatch_get_main_queue()) {
        // Update the UI code 
    }
}

नोट: उपयोगकर्ता-इंटरफ़ेस के किसी भी अपडेट को मुख्य धागे पर बुलाया जाना चाहिए! सुनिश्चित करें, कि आपने UI अपडेट के लिए कोड dispatch_async(dispatch_get_main_queue()) { ... } अंदर डाल दिया है

समवर्ती लूप

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

इस लूप पर विचार करें:

for index in 0 ..< iterations {
    // Do something computationally expensive here
}

आप उन गणनाओं को समवर्ती concurrentPerform (स्विफ्ट 3 में) या dispatch_apply (स्विफ्ट 2 में) का उपयोग करके कर सकते हैं:

3.0
DispatchQueue.concurrentPerform(iterations: iterations) { index in
    // Do something computationally expensive here
}
3.0
dispatch_apply(iterations, queue) { index in
    // Do something computationally expensive here
}

लूप क्लोजर को प्रत्येक index लिए 0 से लागू किया जाएगा, लेकिन iterations शामिल नहीं किया जाएगा। इन पुनरावृत्तियों को एक दूसरे के संबंध में समवर्ती रूप से चलाया जाएगा, और इस प्रकार वे चलने वाले आदेश की गारंटी नहीं है। किसी भी समय समवर्ती रूप से होने वाली पुनरावृत्तियों की वास्तविक संख्या आमतौर पर प्रश्न में डिवाइस की क्षमताओं द्वारा निर्धारित की जाती है (जैसे कि डिवाइस में कितने कोर हैं)।

कुछ विशेष विचार:

  • concurrentPerform / dispatch_apply एक दूसरे के संबंध में समवर्ती छोरों को चला सकते हैं, लेकिन यह सब उस थ्रेड के संबंध में समकालिक रूप से होता है जहां से आप इसे कहते हैं। तो, इसे मुख्य धागे से न कहें, क्योंकि यह उस धागे को तब तक अवरुद्ध करेगा जब तक कि लूप नहीं हो जाता है।

  • क्योंकि ये छोर एक दूसरे के संबंध में समवर्ती होते हैं, आप परिणामों की थ्रेड-सुरक्षा सुनिश्चित करने के लिए जिम्मेदार हैं। उदाहरण के लिए, यदि इन कम्प्यूटेशनल रूप से महंगी गणनाओं के परिणामों के साथ कुछ शब्दकोश अपडेट कर रहे हैं, तो उन अपडेट को स्वयं को सिंक्रनाइज़ करना सुनिश्चित करें।

  • ध्यान दें, समवर्ती छोरों को चलाने में जुड़े कुछ ओवरहेड हैं। इस प्रकार, यदि लूप के अंदर की जा रही गणना पर्याप्त रूप से गहन रूप से गहन नहीं है, तो आप पा सकते हैं कि समवर्ती छोरों का उपयोग करके प्राप्त किसी भी प्रदर्शन को कम किया जा सकता है, यदि पूरी तरह से ऑफसेट नहीं किया जाता है, तो इन सभी समवर्ती थ्रेड के सिंक्रनाइज़ेशन के साथ जुड़े ओवरहेड द्वारा।

    तो, आप लूप के प्रत्येक पुनरावृत्ति में किए जाने वाले कार्य की सही मात्रा निर्धारित कर रहे हैं। यदि गणना बहुत सरल है, तो आप प्रति लूप में अधिक कार्य शामिल करने के लिए "स्ट्राइडिंग" को नियोजित कर सकते हैं। उदाहरण के लिए, 1 मिलियन तुच्छ गणनाओं के साथ समवर्ती लूप करने के बजाय, आप अपने लूप में 100 पुनरावृत्तियों कर सकते हैं, प्रति लूप 10,000 गणनाएं कर रहे हैं। इस तरह से प्रत्येक थ्रेड पर पर्याप्त कार्य किया जा रहा है, इसलिए इन समवर्ती छोरों के प्रबंधन से जुड़े ओवरहेड कम महत्वपूर्ण हो जाते हैं।

एक ऑपरेशन क्यू में चल रहे कार्य

आप किसी कार्य OperationQueue एक पंक्ति के रूप में सोच सकते हैं जो निष्पादित होने की प्रतीक्षा कर रही है। जीसीडी में प्रेषण कतारों के विपरीत, ऑपरेशन कतार एफआईएफओ (पहले-पहले-बाहर) नहीं हैं। इसके बजाय, वे कार्यों को निष्पादित करते हैं जैसे ही वे निष्पादित करने के लिए तैयार होते हैं, जब तक कि इसके लिए अनुमति देने के लिए पर्याप्त सिस्टम संसाधन नहीं होते हैं।

मुख्य OperationQueue प्राप्त करें:

3.0
let mainQueue = OperationQueue.main

एक कस्टम OperationQueue बनाएँ:

3.0
let queue = OperationQueue()
queue.name = "My Queue"
queue.qualityOfService = .default

सेवा की गुणवत्ता कार्य के महत्व को निर्दिष्ट करती है, या उपयोगकर्ता को कार्य से तत्काल परिणाम पर गिनने की कितनी संभावना है।

एक Operation में एक OperationQueue जोड़ें:

3.0
// An instance of some Operation subclass
let operation = BlockOperation {
    // perform task here
}

queue.addOperation(operation)

किसी OperationQueue लिए एक ब्लॉक जोड़ें:

3.0
myQueue.addOperation {
    // some task
}

एक OperationQueue कई Operation जोड़ें:

3.0
let operations = [Operation]()
// Fill array with Operations

myQueue.addOperation(operations)

समायोजित करें कि कितने Operation s कतार के भीतर समवर्ती चलाए जा सकते हैं:

myQueue.maxConcurrentOperationCount = 3 // 3 operations may execute at once

// Sets number of concurrent operations based on current system conditions
myQueue.maxConcurrentOperationCount = NSOperationQueueDefaultMaxConcurrentOperationCount

एक कतार को निलंबित करने से इसे किसी भी मौजूदा, बिना ऑपरेशन के या कतार में जोड़े गए किसी भी नए संचालन का निष्पादन शुरू करने से रोका जा सकेगा। इस कतार को फिर से शुरू करने का तरीका यह है कि वापस false को सेट किया isSuspended :

3.0
myQueue.isSuspended = true

// Re-enable execution
myQueue.isSuspended = false

एक OperationQueue निलंबित करना उन कार्यों को रोकना या रद्द करना नहीं है जो पहले से ही निष्पादित हो रहे हैं। केवल एक कतार को निलंबित करने का प्रयास करना चाहिए जिसे आपने बनाया है, न कि वैश्विक कतार या मुख्य कतार।

उच्च-स्तरीय संचालन बनाना

फाउंडेशन फ्रेमवर्क Operation प्रकार प्रदान करता है, जो एक उच्च-स्तरीय ऑब्जेक्ट का प्रतिनिधित्व करता है जो कार्य के एक हिस्से को कूटबद्ध करता है जिसे एक कतार में निष्पादित किया जा सकता है। न केवल कतार उन कार्यों के प्रदर्शन को समन्वित करती है, बल्कि आप संचालन के बीच निर्भरता भी स्थापित कर सकते हैं, रद्द करने योग्य संचालन बना सकते हैं, ऑपरेशन कतार द्वारा नियोजित संगामिति की डिग्री को बाधित कर सकते हैं, आदि।

Operation तब निष्पादित करने के लिए तैयार हो जाता है जब उसके सभी आश्रित निष्पादन को समाप्त कर देते हैं। isReady प्रॉपर्टी तब true बदलती true

एक साधारण गैर-समवर्ती Operation उपवर्ग बनाएं:

3.0
class MyOperation: Operation {

    init(<parameters>) {
        // Do any setup work here
    }

    override func main() {
        // Perform the task
    }

}
2.3
class MyOperation: NSOperation {

    init(<parameters>) {
        // Do any setup work here
    }

    override func main() {
        // Perform the task
    }

}

एक ऑपरेशन में एक OperationQueue जोड़ें:

1.0
myQueue.addOperation(operation)

यह कतार पर समवर्ती रूप से संचालन को निष्पादित करेगा।

एक Operation पर निर्भरता की व्यवस्था करें।

निर्भरताएँ अन्य Operation s को परिभाषित करती हैं जिन्हें पहले एक कतार में निष्पादित किया जाना चाहिए इससे पहले कि Operation को निष्पादित करने के लिए तैयार माना जाता है।

1.0
operation2.addDependency(operation1)

operation2.removeDependency(operation1)

एक कतार के बिना एक Operation चलाएं:

1.0
   operation.start()

निर्भरता को नजरअंदाज किया जाएगा। यदि यह एक समवर्ती ऑपरेशन है, तब भी कार्य को समवर्ती रूप से निष्पादित किया जा सकता है यदि इसकी start विधि ऑफ़लोड पृष्ठभूमि कतारों में काम करती है।

समवर्ती संचालन।

यदि वह कार्य जो एक Operation को करना है, स्वयं, अतुल्यकालिक है, (जैसे URLSession डेटा कार्य), तो आपको Operation को समवर्ती Operation रूप में लागू करना चाहिए। इस स्थिति में, आपका isAsynchronous क्रियान्वयन true होना चाहिए, आपके पास आम तौर पर start विधि होगी जो कुछ सेटअप करती है, फिर इसकी main विधि को कॉल करती है जो वास्तव में कार्य को निष्पादित करती है।

जब एक अतुल्यकालिक Operation को लागू करना शुरू होता है तो आपको लागू करना आवश्यक होता है। isExecuting , isFinished तरीके और isFinished । इसलिए, जब निष्पादन शुरू होता है, isExecuting संपत्ति में परिवर्तन true जाता true । जब कोई Operation अपना कार्य पूरा करता है, तो isExecuting को false सेट किया जाता false , और isFinished को true सेट किया जाता true । आपरेशन यदि यह दोनों रद्द कर दिया गया isCancelled और isFinished करने के लिए परिवर्तन true । ये सभी गुण मुख्य-माननीय हैं।

एक Operation रद्द करें।

कॉलिंग cancel बस isCancelled प्रॉपर्टी true बदल जाती true । अपने स्वयं के Operation उपवर्ग के भीतर से रद्द करने का जवाब देने के लिए, आपको समय-समय पर main से कम से कम और उचित रूप से जवाब में अलग- isCancelled के मूल्य की जांच करनी चाहिए।

1.0
operation.cancel()


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow