आप थ्रेडिंग मॉडल को बहुत समझ नहीं पाते हैं और यदि आप वास्तव में समझने के बिना एसिंक्रोनस कोड जोड़ना शुरू करते हैं तो आप पैर में खुद को शूट करने जा रहे हैं।
आपके द्वारा लिखे गए कोड मुख्य अनुप्रयोग धागे में चलते हैं। लेकिन जब आप इसके बारे में सोचते हैं, तो आपको main
फ़ंक्शन नहीं लिखना पड़ता है - आप केवल एप्लिकेशन प्रतिनिधि और ईवेंट कॉलबैक (जैसे टच हैंडलर) को लागू करते हैं और किसी भी तरह से समय आने पर वे स्वचालित रूप से चलते हैं। यह एक जादू नहीं है, यह केवल Run Loop नामक कोको वस्तु है।
रन लूप एक ऑब्जेक्ट है जो सभी घटनाओं को प्राप्त करता है, प्रक्रिया टाइमर (NSTimer
में) और आपका कोड चलाता है। इसका मतलब है कि जब आप, उदाहरण के लिए, कुछ करना है जब उपयोगकर्ता एक बटन टैप करता, कॉल पेड़ इस तरह एक सा दिखता है:
main thread running
main run loop
// fire timers
// receive events — aha, here we have an event, let’s call the handler
view::touchesBegan…
// use tapped some button, let’s fire the callback
someButton::touchUpInside
yourCode
अब yourCode
कि आप क्या करना चाहते हैं करता है और भागो लूप चल जारी है। लेकिन जब आपका कोड समाप्त होने में बहुत लंबा समय लगता है, जैसे कि आपके मामले में, रन लूप को प्रतीक्षा करनी है और इसलिए आपके कोड समाप्त होने तक ईवेंट संसाधित नहीं होंगे। यह वही है जो आप अपने आवेदन में देखते हैं।
स्थिति को हल करने के लिए आपको किसी अन्य धागे में लंबे ऑपरेशन को चलाने के लिए है। यह बहुत कठिन नहीं है, लेकिन फिर भी आपको कुछ संभावित समस्याओं के बारे में सोचना होगा।एक और धागा में चल रहा है performSelectorInBackground
बुला के रूप में के रूप में आसान हो सकता है:
[appDelegate performSelectorInBackground:@selector(GetApps) withObject:nil];
और अब आप इस तरह के मुख्य पर एक अधिसूचना एक चयनकर्ता का उपयोग करके या फोन कर के रूप में, एक तरह से आवेदन को बताने के लिए सोचने के लिए डेटा लोड किया गया है है धागा। वैसे: आवेदन प्रतिनिधि (या डेटा लोड करने के लिए आवेदन प्रतिनिधि का उपयोग करके) में डेटा संग्रहीत करना बहुत ही सुरुचिपूर्ण समाधान नहीं है, लेकिन यह एक और कहानी है।
यदि आप performSelectorInBackground
समाधान चुनते हैं, तो memory management in secondary threads के बारे में संबंधित प्रश्न देखें। आपको अपने स्वयं के ऑटोरेलीज पूल की आवश्यकता होगी ताकि आप ऑटोरेलेज्ड ऑब्जेक्ट्स को रिसाव न करें।
कुछ समय के बाद जवाब अपडेट कर रहा है - आजकल यह आम तौर पर ग्रांड सेंट्रल डिस्पैच का उपयोग कर पृष्ठभूमि में कोड को चलाने के लिए सबसे अच्छा है:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// No explicit autorelease pool needed here.
// The code runs in background, not strangling
// the main run loop.
[self doSomeLongOperation];
dispatch_sync(dispatch_get_main_queue(), ^{
// This will be called on the main thread, so that
// you can update the UI, for example.
[self longOperationDone];
});
});
हाँ, मैंने इन चीजों पर पढ़ा है, अभी भी समझने के लिए बहुत कुछ है, लेकिन मुझे यह मिल जाएगा, आपने मुझे सही दिशा में रखा है। धन्यवाद। मैं टीबीएक्सएमएल घटक का उपयोग कर रहा था, इसलिए, मुझे लगता है कि यह समझने के लिए मुझे एक सरल लिखना होगा कि यह कैसे काम करता है। वैसे भी, एक और संबंधित सवाल यह था कि, यदि उपयोगकर्ता दृश्य को बंद करना चुनता है, तो क्या selectorInBackground कॉल को समाप्त करने के लिए वैसे भी है? ViewDidUnload .. पर? – Sam
यह निर्भर करता है। साधारण मामलों में आप केवल इस मुद्दे को अनदेखा कर सकते हैं और अधिसूचना भाग को कोड कर सकते हैं ताकि जब दृश्य को जल्दी से खारिज कर दिया जाए तो यह तोड़ नहीं जाता है। एसिंक्रोनस 'NSURLConnection' मोड या ऑपरेशन कतार का उपयोग करके एक और बुलेट प्रूफ समाधान लिखा जा सकता है, दोनों में ऑपरेशन को प्रगति पर रद्द करने का एक तरीका है। – zoul
अंतिम कोड स्निपेट अद्भुत है, यह वही है जो मैं ढूंढ रहा हूं। बहुत धन्यवाद! – kisileno