एनएसओपरेशन बनाम ग्रैंड सेंट्रल डिस्पैच


465

मैं iOS के लिए समवर्ती प्रोग्रामिंग के बारे में सीख रहा हूं। अब तक मैंने NSOperation/NSOperationQueue और के बारे में पढ़ा है GCDपर और इसके विपरीत का उपयोग करने के कारण क्या हैं ?NSOperationQueueGCD

दोनों की तरह लगता है GCDऔर उपयोगकर्ता से NSOperationQueueस्पष्ट निर्माण को NSThreadsदूर करता है। हालाँकि दोनों दृष्टिकोणों के बीच का संबंध मेरे लिए इतना स्पष्ट नहीं है कि किसी भी प्रतिक्रिया की सराहना की जाए!


10
अच्छे प्रश्न के लिए +1 - परिणामों पर उत्सुक। अब तक, मैंने सिर्फ पढ़ा है कि जीसीडी को आसानी से सीपीयू कोर के माध्यम से भेजा जा सकता है, इसे "नया हॉट शिट" कहा जा सकता है।
तक


जवाबों:


517

GCDएक निम्न-स्तरीय सी-आधारित एपीआई है जो कार्य-आधारित संगामिति मॉडल के बहुत सरल उपयोग को सक्षम करता है। NSOperationऔर NSOperationQueueऑब्जेक्टिव-सी क्लास हैं जो एक समान कार्य करते हैं। NSOperationपहले पेश किया गया था, लेकिन 10.5 और iOS 2 के रूप में , NSOperationQueueऔर दोस्तों को आंतरिक रूप से उपयोग किया जाता है GCD

सामान्य तौर पर, आपको एब्सट्रैक्शन के उच्चतम स्तर का उपयोग करना चाहिए जो आपकी आवश्यकताओं के अनुरूप हो। इसका मतलब है कि आपको आम तौर पर NSOperationQueueइसके बजाय का उपयोग करना चाहिए GCD, जब तक कि आपको कुछ ऐसा करने की आवश्यकता NSOperationQueueनहीं है जो समर्थन नहीं करता है।

ध्यान दें कि NSOperationQueueGCD का "डम्बल-डाउन" संस्करण नहीं है; वास्तव में, कई चीजें हैं जो आप बहुत सरलता से कर सकते हैं NSOperationQueueकि शुद्ध के साथ बहुत सारे काम करें GCD। (उदाहरण: बैंडविड्थ-विवश कतारें जो केवल एक समय में एन ऑपरेशन चलाती हैं, संचालन के बीच निर्भरता स्थापित करती हैं। दोनों के साथ बहुत सरल NSOperation, बहुत मुश्किल है GCD।) Apple ने GCD का लाभ उठाने के लिए बहुत अच्छा वस्तु-अनुकूल एपीआई बनाने के लिए कड़ी मेहनत की है NSOperation। जब तक आपके पास कोई कारण न हो, उनके काम का लाभ उठाएं।

कैविएट : दूसरी ओर, अगर आपको वास्तव में बस एक ब्लॉक भेजने की आवश्यकता है, और जो अतिरिक्त कार्यक्षमता NSOperationQueueप्रदान करता है, उसमें से किसी की आवश्यकता नहीं है , तो जीसीडी का उपयोग करने में कुछ भी गलत नहीं है। बस यह सुनिश्चित करें कि यह काम के लिए सही उपकरण है।


1
NSOperation विशिष्ट अमूर्त वर्ग होना।
रोशन

3
@ कैंडी यह वास्तव में विपरीत है, जीसीडी का उपयोग एनएसओपरेशन (कम से कम आईओएस और ओएस एक्स के बाद के संस्करणों में) द्वारा किया जाता है।
गार्तुनमून

1
@BJ होमर हम धारावाहिक प्रेषण कतार में कार्य जोड़ सकते हैं ताकि वे अस्वस्थता को दूर कर सकें। तो बस कैसे ऑपरेशन कतार से फायदा है कि
राज अग्रवाल

3
@RajAggrawal हां, यह काम करता है ... लेकिन फिर आप एक सीरियल कतार के साथ फंस गए हैं। NSOperation "इस ऑपरेशन को अंजाम दे सकता है, जब उन तीनों को किया जाता है, लेकिन समवर्ती अन्य सभी सामान के साथ चल रहा है।" ऑपरेशन की निर्भरता भी अलग-अलग कतारों पर संचालन के बीच मौजूद हो सकती है। अधिकांश लोगों को इसकी आवश्यकता नहीं होगी, लेकिन यदि आप करते हैं, तो NSOperation एक बेहतर विकल्प होगा।
बीजे होमर

369

संबंधित प्रश्न के मेरे उत्तर के अनुरूप , मैं बीजे से असहमत होने जा रहा हूं और आपको पहले सुझाव देता हूं कि आप जीसीडी को NSOperation / NSOperationQueue पर देखें, जब तक कि उत्तरार्द्ध आपको कुछ ऐसा प्रदान नहीं करता है जिसकी आपको जीसीडी आवश्यकता नहीं है।

जीसीडी से पहले, मैंने संगामिति के प्रबंधन के लिए अपने अनुप्रयोगों के भीतर कई NSOperations / NSOperationQueues का उपयोग किया। हालाँकि, जब से मैंने नियमित रूप से GCD का उपयोग करना शुरू किया, मैंने लगभग पूरी तरह से NSOperations और NSOperationQueues को ब्लॉक और प्रेषण कतारों से बदल दिया है। यह इस बात से आया है कि मैंने अभ्यास में दोनों तकनीकों का उपयोग कैसे किया है, और प्रोफाइलिंग से मैंने उन पर प्रदर्शन किया है।

सबसे पहले, NSOperations और NSOperationQueues का उपयोग करते समय ओवरहेड की एक nontrivial राशि होती है। ये कोको की वस्तुएं हैं, और उन्हें आवंटित करने और उन्हें निपटाने की आवश्यकता है। एक iOS एप्लिकेशन में जो मैंने लिखा था जो 60 एफपीएस में 3-डी दृश्य प्रस्तुत करता है, मैं प्रत्येक गाया फ्रेम को एनकैप करने के लिए NSOperations का उपयोग कर रहा था। जब मैंने इसे प्रोफाइल किया, तो इन NSOperations के निर्माण और अशांति चल रहे एप्लिकेशन में सीपीयू चक्रों के एक महत्वपूर्ण हिस्से के लिए जिम्मेदार था, और चीजों को धीमा कर रहा था। मैंने इन्हें साधारण ब्लॉकों और एक जीसीडी सीरियल कतार के साथ बदल दिया, और यह ओवरहेड गायब हो गया, जिसके कारण यह बेहतर प्रदर्शन प्रदान कर रहा है। यह एकमात्र जगह नहीं थी जहाँ मैंने NSOperations का उपयोग करने से अधिक ध्यान दिया था, और मैंने इसे मैक और iOS दोनों पर देखा है।

दूसरा, ब्लॉक-आधारित प्रेषण कोड के लिए एक लालित्य है जो NSOperations का उपयोग करते समय मिलान करना मुश्किल है। यह एक ब्लॉक में कोड की कुछ पंक्तियों को लपेटने और एक सीरियल या समवर्ती कतार पर किए जाने के लिए इसे भेजने के लिए अविश्वसनीय रूप से सुविधाजनक है, जहां एक कस्टम NSOperation या NSInvocationOperation बनाने के लिए ऐसा करने के लिए बहुत अधिक सहायक कोड की आवश्यकता होती है। मुझे पता है कि आप एक NSBlockOperation का उपयोग कर सकते हैं, लेकिन आप तब GCD को कुछ भेज सकते हैं। इस कोड को अपने आवेदन में संबंधित प्रसंस्करण के साथ ब्लॉक में लपेटकर अलग-अलग तरीकों या कस्टम NSOperations जो इन कार्यों को अंजाम देते हैं, की तुलना में बेहतर कोड संगठन के लिए मेरी राय में होता है।

NSOperations और NSOperationQueues का अभी भी बहुत अच्छा उपयोग है। GCD पर निर्भरता की कोई वास्तविक अवधारणा नहीं है, जहां NSOperationQueues सुंदर जटिल निर्भरता ग्राफ सेट कर सकते हैं। मैं कुछ मामलों में इसके लिए NSOperationQueues का उपयोग करता हूं।

कुल मिलाकर, जब मैं आमतौर पर कार्य को पूरा करने वाले उच्चतम स्तर के अमूर्त का उपयोग करने की वकालत करता हूं, तो यह एक ऐसा मामला है जहां मैं जीसीडी के निचले स्तर के एपीआई के लिए तर्क देता हूं। IOS और Mac डेवलपर्स के बीच मैंने इस बारे में बात की है, विशाल बहुमत NSOperations पर GCD का उपयोग करने के लिए चुनते हैं जब तक कि वे इसके लिए समर्थन के बिना ओएस संस्करणों को लक्षित नहीं कर रहे हैं (आईओएस 4.0 और स्नो लेपर्ड से पहले)।


20
मैं केवल हल्के से असहमत हूं; मैं सादे जीसीडी का काफी उपयोग करता हूं। लेकिन मुझे लगता है कि आप इस उत्तर में NSBlockOperation को बहुत अधिक छूट देते हैं। NSOperationQueue (निर्भरता, डिबगैबिलिटी, आदि) के सभी लाभ ब्लॉक संचालन पर भी लागू होते हैं।
बीजे होमर

4
@BJHomer - मुझे लगता है कि NSBlockOperation से बचना मेरे मामले में व्यक्तिगत पसंद का मामला है, हालाँकि मैंने सामान्य रूप से NSOperations से किनारा कर लिया है, क्योंकि ओवरहेड को देखने के बाद उनके उपयोग से कुछ अनुप्रयोगों को नीचे खींच लिया जाता है। यदि मैं ब्लॉकों का उपयोग करने जा रहा हूं, तो मुझे निर्भरता समर्थन की आवश्यकता होने पर दुर्लभ अपवाद के साथ, जीसीडी पर सभी में जाने की अनुमति है।
ब्रैड लार्सन

1
+1, इस विश्लेषण के लिए धन्यवाद। लगता है कि Apple दोनों की वकालत कर रहा है (जैसे WWDC 2012 के समवर्ती UI पर सत्र), इसलिए यह बहुत सराहनीय है।
orip

1
@VolureDarkAngel - जैसे डिस्पैच को संभालने में GCD बेहद तेज है। जब तक आप किसी भी तरह से अपडेट का एक ढेर धीमी आई / ओ एक्सेस या इस तरह के कुछ के कारण वापस नहीं करते हैं, तब तक यह आपकी अड़चन नहीं होनी चाहिए। शायद यहाँ ऐसा नहीं है, हालाँकि।
ब्रैड लार्सन

1
@ asma22 - गणना के लिए यह सामान्य है कि चंक्स में किया जा सकता है, लेकिन एक चरण की अंतिम गणना को कई पिछले चरणों के परिणामों की आवश्यकता हो सकती है। उस स्थिति में, आप यह कर सकते हैं कि बाद में ऑपरेशन पहले के ऑपरेशनों पर निर्भर करता है, और शेड्यूलिंग को ऐसे प्रबंधित किया जाएगा कि वे सभी पिछले एक रन से पहले पूरा हो जाएं।
ब्रैड लार्सन

101

GCDएक निम्न-स्तरीय C- आधारित API है।
NSOperationऔर NSOperationQueueउद्देश्य-सी कक्षाएं हैं।
NSOperationQueueउद्देश्य सी आवरण है GCD। यदि आप NSOperation का उपयोग कर रहे हैं, तो आप स्पष्ट रूप से ग्रैंड सेंट्रल डिस्पैच का उपयोग कर रहे हैं

NSOperation पर GCD का लाभ:
i। कार्यान्वयन कार्यान्वयन के
लिए GCDबहुत हल्का होता है, वजन
NSOperationQueueजटिल और भारी होता है

GCD से अधिक लाभ

मैं। ऑपरेशन पर नियंत्रण
आप रोक सकते हैं, रद्द कर सकते हैं, फिर से शुरू कर सकते हैंNSOperation

ii। निर्भरताएँ जिन्हें
आप दो NSOperations
ऑपरेशन के बीच एक निर्भरता स्थापित कर सकते हैं, तब तक शुरू नहीं होगी जब तक कि उसकी सभी निर्भरताएं समाप्त होने के बाद वापस नहीं आतीं।

iii। ऑपरेशन
की स्थिति एक ऑपरेशन या ऑपरेशन कतार की स्थिति की निगरानी कर सकती है। तैयार, निष्पादित या समाप्त

iv। ऑपरेशन की अधिकतम संख्या
आप कतारबद्ध संचालन की अधिकतम संख्या निर्दिष्ट कर सकते हैं जो एक साथ चल सकती हैं

जबGCDNSOperation
आप या जब आप कतार से ऊपर का नियंत्रण चाहते हैं (उपर्युक्त सभी) का उपयोग करें NSOperation और सरल मामलों के लिए जहां आप कम ओवरहेड चाहते हैं (आप बहुत कम अतिरिक्त काम के साथ "पृष्ठभूमि में" कुछ काम करना चाहते हैं)GCD

रेफरी:
https://cocoacasts.com/choosing-between-nsoperation-and-grand-central-dispatch/ http://iosinfopot.blogspot.in/2015/08/nsthread-vs-gcd-vs-nsoperationqueue.html http : //nshipster.com/nsoperation/


जैसा कि कहा गया है, ऑपरेशन की अधिकतम संख्या को NSOperationQueue में निर्दिष्ट किया जा सकता है, फिर GCD में अधिकतम संख्या में प्रचालन (प्रेषण कतारें) क्या हो सकती हैं? मान लीजिए मेरे पास एक परियोजना है, तो मैं कितने ऑपरेशन (प्रेषण कतारों) कर सकता हूं। या उनकी कोई अधिकतम सीमा है जो हम कर सकते हैं।
रोशन साह

यह सिस्टम की स्थितियों पर निर्भर करता है यहां विस्तृत जानकारी दी गई है: stackoverflow.com/questions/14995801/…
संग्राम शिवंकर

हम डिस्पैचवर्क इटेम का उपयोग करके जीसीडी में कार्य को रद्द कर सकते हैं और हम निलंबित भी कर सकते हैं और फिर से शुरू कर सकते हैं
अंकित

@Ankitgarg DispatchWorkItem पर कॉलिंग रद्द करने से कार्य निष्पादित होने से रुक जाएंगे यदि उन्हें अभी तक चलाया जाना है, लेकिन कुछ ऐसा नहीं होगा जो पहले से ही निष्पादित हो रहा हो। और आप एक डिस्पैचवर्क इटेम को कैसे रोकते / फिर से शुरू करते हैं ??
अभिमुर्लीधरन

34

GCD पर NSOperation पसंद करने का एक अन्य कारण NSOperation का रद्दकरण तंत्र है। उदाहरण के लिए, एक ऐप्प जैसे 500px जो दर्जनों फ़ोटो दिखाता है, NSOperation का उपयोग करें जब हम तालिका दृश्य या संग्रह दृश्य स्क्रॉल करते हैं तो हम अदृश्य छवि कोशिकाओं के अनुरोधों को रद्द कर सकते हैं, इससे ऐप प्रदर्शन में सुधार हो सकता है और मेमोरी फ़ुटप्रिंट कम हो सकता है। GCD आसानी से इसका समर्थन नहीं कर सकता।

इसके अलावा NSOperation के साथ KVO संभव हो सकता है।

यहाँ Eschaton का एक लेख है जो पढ़ने लायक है।


4
यह ध्यान देने योग्य है कि यदि आप जो रद्द कर रहे हैं वह छवि लोड करने का नेटवर्क संचालन है, तो आपको इसके NSOperationलिए, इस कार्यक्षमता को प्रदान करने NSURLSessionTask.cancelऔर NSURLSession.invalidateAndCancelप्रदान करने की आवश्यकता नहीं है । सामान्य तौर पर, NSURLSessionएक की कार्यक्षमता के कुछ प्रदान करता है NSOperationQueue, के रूप में NSURLSessionTaskएक की कार्यक्षमता के कुछ प्रदान करता हैNSOperation
शैवाल

@algal जैसा कि यहां बताया गया है ( stackoverflow.com/questions/21918722/… ), ऐसा लगता है कि NSURLSession NSOperationQueue का उपयोग बिल्डिंग ब्लॉक के रूप में करता है।
कलन नवरथने

33

जीसीडी वास्तव में NSOperationQueue की तुलना में निम्न स्तर का है, इसका प्रमुख लाभ यह है कि इसका कार्यान्वयन बहुत हल्का है और लॉक-फ्री एल्गोरिदम और प्रदर्शन पर केंद्रित है।

NSOperationQueue ऐसी सुविधाएं प्रदान करता है जो GCD में उपलब्ध नहीं हैं, लेकिन वे गैर-तुच्छ लागत पर आते हैं, NSOperationQueue का कार्यान्वयन जटिल और भारी वजन है, इसमें बहुत सारे लॉकिंग शामिल हैं, और आंतरिक रूप से केवल बहुत ही कम समय में PCD का उपयोग करता है।

यदि आपको सभी साधनों द्वारा NSOperationQueue द्वारा दी गई सुविधाओं की आवश्यकता है, तो इसका उपयोग करें, लेकिन यदि GCD आपकी आवश्यकताओं के लिए पर्याप्त है, तो मैं इसे बेहतर प्रदर्शन, काफी कम CPU और बिजली की लागत और अधिक लचीलेपन के लिए सीधे उपयोग करने की सलाह दूंगा।


24

NSQueueOperations और GCD दोनों ही यूआई एप्लीकेशन मेन ट्रेड को मुक्त करके अलग थ्रेड्स पर पृष्ठभूमि में भारी गणना कार्य निष्पादित करने की अनुमति देते हैं।

खैर, पिछली पोस्ट के आधार पर हम देखते हैं कि NSOperations में AddD dependency है ताकि आप क्रमिक रूप से एक के बाद एक अपने ऑपरेशन को कतारबद्ध कर सकें।

लेकिन मैंने जीसीडी धारावाहिक कतारों के बारे में भी पढ़ा है जो आप अपने प्रचालनों को डिस्पैच_क्युए_क्रिएट का उपयोग करके कतार में चला सकते हैं। यह क्रमबद्ध तरीके से एक के बाद एक कई ऑपरेशन चलाने की अनुमति देगा।

GCD पर NSQueueOperation लाभ:

  1. यह निर्भरता को जोड़ने की अनुमति देता है और आपको निर्भरता को हटाने की अनुमति देता है ताकि एक लेन-देन के लिए आप निर्भरता का उपयोग करके अनुक्रमिक चला सकें और अन्य लेनदेन के लिए समवर्ती रूप से चल सकें जबकि जीसीडी इस तरह से चलने की अनुमति नहीं देता है।

  2. किसी ऑपरेशन को रद्द करना आसान है यदि वह कतार में है तो उसे रोका जा सकता है यदि वह चल रहा है।

  3. आप समवर्ती संचालन की अधिकतम संख्या को परिभाषित कर सकते हैं।

  4. आप ऑपरेशन को निलंबित कर सकते हैं जो वे कतार में हैं

  5. आप पा सकते हैं कि कतार में कितने लंबित ऑपरेशन हैं।


6

जीसीडी का उपयोग करना बहुत आसान है - यदि आप पृष्ठभूमि में कुछ करना चाहते हैं, तो आपको केवल कोड लिखने और इसे पृष्ठभूमि की कतार पर भेजने की आवश्यकता है। NSOperation के साथ एक ही काम करना बहुत अतिरिक्त काम है।

NSOperation का लाभ यह है कि (a) आपके पास एक वास्तविक वस्तु है जिससे आप संदेश भेज सकते हैं और (b) जिसे आप NSOperation रद्द कर सकते हैं। यह तुच्छ नहीं है। आपको NSOperation को subclass करने की आवश्यकता है, आपको अपना कोड सही ढंग से लिखना होगा ताकि किसी कार्य को सही ढंग से पूरा करने और रद्द करने का कार्य सही ढंग से हो सके। तो साधारण चीजों के लिए आप GCD का उपयोग करते हैं, और अधिक जटिल चीजों के लिए आप NSOperation का उपवर्ग बनाते हैं। (उपवर्ग NSInvocationOperation और NSBlockOperation हैं, लेकिन वे जो कुछ भी करते हैं वह GCD के साथ आसान है, इसलिए उनका उपयोग करने का कोई अच्छा कारण नहीं है)।


3

खैर, NSOperations बस एक एपीआई है जो ग्रैंड सेंट्रल डिस्पैच के शीर्ष पर बनाया गया है। इसलिए जब आप NSOperations का उपयोग कर रहे हैं, तो आप वास्तव में अभी भी ग्रैंड सेंट्रल डिस्पैच का उपयोग कर रहे हैं। यह सिर्फ इतना है कि NSOperations आपको कुछ फैंसी सुविधाएँ प्रदान करते हैं जो आपको पसंद हो सकती हैं। आप कुछ परिचालनों को अन्य प्रचालनों पर निर्भर बना सकते हैं, आपके द्वारा आइटमों को छांटने के बाद कतारों को फिर से चालू कर सकते हैं, और इस तरह की अन्य चीजें। वास्तव में, ImageGrabber पहले से ही NSOperations और ऑपरेशन कतार का उपयोग कर रहा है! ASIHTTPRequest हुड के तहत उनका उपयोग करता है, और यदि आप चाहें तो आप इसे अलग-अलग व्यवहार के लिए उपयोग की जाने वाली ऑपरेशन कतार को कॉन्फ़िगर कर सकते हैं। तो आपको कौन सा उपयोग करना चाहिए? जो भी आपके ऐप के लिए मायने रखता है। इस एप्लिकेशन के लिए यह बहुत आसान है, इसलिए हमने सीधे ग्रैंड सेंट्रल डिस्पैच का उपयोग किया, NSOperation की फैंसी विशेषताओं की कोई आवश्यकता नहीं है। लेकिन अगर आपको अपने ऐप के लिए उनकी आवश्यकता है, तो इसका उपयोग करने के लिए स्वतंत्र महसूस करें!

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.