दिलचस्प पोस्ट
स्प्रिंग बीन में Autowiring (@Component) नए कीवर्ड के साथ बनाया गया MATLAB के सबसे निकटतम नाम क्या है? स्काले क्यों एकाधिक पैरामीटर सूचियों और प्रति सूची में कई पैरामीटर प्रदान करता है? एंड्रॉइड: फिक्स्ड आस्पेक्ट अनुपात के साथ कैमरे के साथ ले जाने के बाद एक छवि क्रॉप करें ट्विटर बूटस्ट्रैप 3 में नेबबार का रंग बदलें Levenshtein दूरी आधारित विधियों बनाम Soundex कैसे जावा से एसक्यूएल सर्वर संग्रहीत कार्यप्रणाली से टेबल-मान मापदंडों को पारित करने के लिए? संबंध के लिए अनुमति अस्वीकृत जावास्क्रिप्ट OOP सर्वोत्तम अभ्यास? मैं सी # में एक प्रोग्राम प्रोग्राम को कैसे हल करता हूं? Matplotlib में एक भूखंड के लिए अक्ष, ticks और लेबल का रंग बदलना हटाने के साथ सूची में लूप पोर्ट और गर्तिका के बीच अंतर क्या है? अजगर में% r का अर्थ क्या है जावास्क्रिप्ट में फ़ाइल खोलें संवाद बॉक्स

ग्रैंड सेंट्रल डिस्पैच (जीसीडी) बनाम प्रदर्शनकर्ता – बेहतर स्पष्टीकरण की आवश्यकता है

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

dispatch_sync(dispatch_get_main_queue(), ^{ [self doit:YES]; }); [self performSelectorOnMainThread:@selector(doit:) withObject:YES waitUntilDone:YES]; 

क्या मैं गलत हूं? यही है, क्या जीसीडी वाले लोगों की तुलना में प्रदर्शनकर्ता * आज्ञाओं में अंतर है? मैंने उन पर बहुत सारे दस्तावेज़ीकरण पढ़ा है, लेकिन अभी तक एक निश्चित जवाब नहीं देखा है।

Solutions Collecting From Web of "ग्रैंड सेंट्रल डिस्पैच (जीसीडी) बनाम प्रदर्शनकर्ता – बेहतर स्पष्टीकरण की आवश्यकता है"

performSelectorOnMainThread: मुख्य थ्रेड पर ऑब्जेक्ट्स को संदेश भेजने के लिए GCD का उपयोग नहीं करता है।

यहां बताया गया है कि दस्तावेज़ीकरण कहां लागू होता है:

 - (void) performSelectorOnMainThread:(SEL) selector withObject:(id) obj waitUntilDone:(BOOL) wait { [[NSRunLoop mainRunLoop] performSelector:selector target:self withObject:obj order:1 modes: NSRunLoopCommonModes]; } 

और प्रदर्शन करने वाले पर performSelector:target:withObject:order:modes: प्रलेखन के अनुसार:

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

जैसा कि याकूब बताते हैं, जबकि वे एक ही दिखाई देते हैं, वे अलग-अलग चीज़ें हैं। वास्तव में, यदि आप पहले से ही मुख्य थ्रेड पर चल रहे हैं, तो मुख्य धागे पर कार्रवाई भेजने के तरीके में एक महत्वपूर्ण अंतर है।

मैं हाल ही में इस पर गया था, जहां मेरे पास एक आम तरीका था जो कभी-कभी मुख्य धागा पर कुछ से चलाया जाता था, कभी-कभी नहीं। कुछ यूआई अपडेटों को सुरक्षित रखने के लिए, मैं -performSelectorOnMainThread: का उपयोग कर रहा था -performSelectorOnMainThread: उनके लिए कोई समस्या नहीं है

जब मैं मुख्य कतार पर dispatch_sync का उपयोग करने के लिए ऊपर स्विच कर दिया, तो जब भी यह विधि मुख्य कतार पर चलायी जायेगी तब अनुप्रयोग डेडलॉक होगा प्रेषण_एसआईएनसीसी पर दस्तावेज पढ़ना, हम देखें:

इस फ़ंक्शन को कॉल करना और डेडलॉक में मौजूदा कतार परिणाम को लक्षित करना।

जहां के लिए -performSelectorOnMainThread: हम देखते हैं

रुकिए

बूलियन जो निर्दिष्ट करता है कि क्या वर्तमान थ्रेड ब्लॉकों तक मुख्य चयनकर्ता के मुख्य थ्रेड पर रिसीवर पर किया जाता है या नहीं। इस थ्रेड को ब्लॉक करने के लिए हाँ निर्दिष्ट करें; अन्यथा, इस पद्धति को तुरंत वापस लेने के लिए कोई निर्दिष्ट नहीं करें।

यदि मौजूदा थ्रेड भी मुख्य धागा है, और आप इस पैरामीटर के लिए हां निर्दिष्ट करते हैं, तो संदेश तुरंत वितरित किया जाता है और संसाधित होता है।

मैं अभी भी जीसीडी की भव्यता को पसंद करता हूं, यह बेहतर संकलन-समय की जांच करता है, और इसके तर्कों आदि के बारे में अधिक लचीलापन आदि है, इसलिए मैंने डेडलॉक को रोकने के लिए इस छोटी सहायक कार्य को बनाया:

 void runOnMainQueueWithoutDeadlocking(void (^block)(void)) { if ([NSThread isMainThread]) { block(); } else { dispatch_sync(dispatch_get_main_queue(), block); } } 

अद्यतन करें: डेव ड्रिबिन के जवाब में प्रेषण_ग्रेड_आर्पर__अभियान dispatch_get_current_queue() पर चेतावनी अनुभाग को इंगित करते हुए, मैंने ऊपर दिए गए कोड में [NSThread isMainThread] का उपयोग करने के लिए बदल दिया है I

मैं तो उपयोग करें

 runOnMainQueueWithoutDeadlocking(^{ //Do stuff }); 

मुख्य धागा पर सुरक्षित करने की आवश्यकता वाले कार्यों को करने के लिए, बिना किसी चिंता के, मूल विधि को किस प्रकार क्रियान्वित किया गया था।

जीसीडी का तरीका अधिक कुशल और संभालना आसान है और केवल आईओएस 4 के बाद ही उपलब्ध है जबकि प्रदर्शनकर्ता को पुराने और नए आईओएस में समर्थन मिलता है।