paint-brush
IOS अनुप्रयोगों में RunLoop का उपयोग कैसे करेंद्वारा@alekseimarinin
4,327 रीडिंग
4,327 रीडिंग

IOS अनुप्रयोगों में RunLoop का उपयोग कैसे करें

द्वारा amarinin5m2024/03/04
Read on Terminal Reader

बहुत लंबा; पढ़ने के लिए

रनलूप एक लूप है जो एक विशिष्ट थ्रेड में आने वाली घटनाओं की प्राप्ति और प्रसंस्करण का समन्वय करता है। डिफ़ॉल्ट रूप से, मुख्य रनलूप हमेशा एप्लिकेशन में चलता रहता है; यह सिस्टम से संदेशों को संसाधित करता है और उन्हें एप्लिकेशन तक पहुंचाता है। सहायक थ्रेड्स को रनलूप की आवश्यकता के स्व-निर्धारण की आवश्यकता होती है, और आपको इसे स्वयं कॉन्फ़िगर और चलाना होगा।
featured image - IOS अनुप्रयोगों में RunLoop का उपयोग कैसे करें
amarinin HackerNoon profile picture

रनलूप क्या है?

रनलूप एक लूप है जो एक विशिष्ट थ्रेड में आने वाली घटनाओं की प्राप्ति और प्रसंस्करण का समन्वय करता है।


रनलूप हर थ्रेड में मौजूद है, लेकिन डिफ़ॉल्ट रूप से, यह स्टैंडबाय मोड में है और कोई काम नहीं करता है।


यदि आवश्यक हो तो डेवलपर इसे चला सकता है, लेकिन यह स्वचालित रूप से काम नहीं करेगा। ऐसा करने के लिए, आपको कोड लिखना होगा.

रनलूप किस समस्या का समाधान करता है?

सबसे पहले, RunLoop को आने वाले कार्यों के प्रवाह को प्रबंधित करने और उन्हें सही समय पर निष्पादित करने के लिए डिज़ाइन किया गया है।


यूआई के साथ काम करते समय यह सबसे अधिक ध्यान देने योग्य है, उदाहरण के लिए, यूआईस्क्रॉलव्यू का उपयोग करते समय।


डिफ़ॉल्ट रूप से, मुख्य रनलूप हमेशा एप्लिकेशन में चलता रहता है; यह सिस्टम से संदेशों को संसाधित करता है और उन्हें एप्लिकेशन तक पहुंचाता है। ऐसे संदेशों का एक उदाहरण, उदाहरण के लिए, एक घटना हो सकती है जब कोई उपयोगकर्ता स्क्रीन पर क्लिक करता है।


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


साथ ही, एप्लिकेशन में सभी टाइमर रनलूप पर निष्पादित होते हैं, इसलिए यदि आपको अपने एप्लिकेशन में उनके साथ इंटरैक्ट करने की आवश्यकता है, तो आपको निश्चित रूप से रनलूप की विशेषताओं का अध्ययन करने की आवश्यकता है।

यह कैसे काम करता है?

रनलूप एक लूप है, और इसमें ऑपरेशन के कई तरीके हैं जो डेवलपर को यह समझने में मदद करते हैं कि किसी विशेष कार्य को कब चलाना है।


तो, RunLoop निम्नलिखित मोड में हो सकता है:

  1. Default - डिफ़ॉल्ट मोड, स्ट्रीम मुफ़्त है, और इसमें बड़े ऑपरेशन सुरक्षित रूप से किए जा सकते हैं।


  2. Tracking - धागा कुछ महत्वपूर्ण कार्य करने में व्यस्त है। इस बिंदु पर, कोई भी कार्य न चलाना, या कम से कम कुछ छोटे कार्य चलाना बेहतर है।


  3. Initialization - यह मोड स्ट्रीम के इनिशियलाइज़ेशन के दौरान एक बार निष्पादित होता है।


  4. EventReceive - यह सिस्टम इवेंट प्राप्त करने के लिए एक आंतरिक मोड है, जिसका आमतौर पर उपयोग नहीं किया जाता है।

  5. Common - एक प्लेसहोल्डर मोड है जिसका कोई व्यावहारिक महत्व नहीं है।


    मुख्य रनलूप पर, ये मोड स्वचालित रूप से स्विच हो जाते हैं; डेवलपर उनका उपयोग समय लेने वाले कार्यों को करने के लिए कर सकता है ताकि उपयोगकर्ता को इंटरफ़ेस हैंग होने का पता न चले। आइए एक उदाहरण देखें.


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


हमारे पास एक UIScrollView है, और हमें मुख्य थ्रेड पर एक बड़ा कार्य करने की आवश्यकता है ताकि उपयोगकर्ता को कुछ भी नज़र न आए।


हम कार्य को सामान्य तरीके से पूरा कर सकते हैं:


 DispatchQueue.main.async { sleep(2) self.tableView.refreshControl?.endRefreshing() }


लेकिन इसका परिणाम बहुत बुरा होने वाला है. उपयोगकर्ता को एप्लिकेशन में महत्वपूर्ण विलंब दिखाई देगा.

यह नकारात्मक प्रभाव इस तथ्य के कारण होता है कि हम इस समय इस पर क्या हो रहा है, इस पर ध्यान दिए बिना किसी कार्य को मुख्य थ्रेड पर चलाते हैं।


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


रनलूप तंत्र का उपयोग करके इससे बचा जा सकता है। आइए इसका उपयोग करके वही तर्क लागू करें:


 CFRunLoopPerformBlock(CFRunLoopGetMain(), CFRunLoopMode.defaultMode.rawValue) { sleep(2) self.tableView.refreshControl?.endRefreshing() }


आइए मैं समझाऊं कि यहां क्या होता है। CFRunLoopPerformBlock फ़ंक्शन RunLoop के माध्यम से निष्पादन के लिए कोड जोड़ता है। कोड ब्लॉक के अलावा, इस फ़ंक्शन में 2 महत्वपूर्ण पैरामीटर हैं।


पहला व्यक्ति यह चुनने के लिए ज़िम्मेदार है कि किस RunLoop को फ़ंक्शन निष्पादित करना चाहिए। इस उदाहरण में, "मुख्य" का उपयोग किया गया है।


दूसरा उस मोड के लिए ज़िम्मेदार है जिसमें कार्य पूरा किया जाएगा।


कुल मिलाकर तीन संभावित मोड हैं:

  • ट्रैकिंग - जब उपयोगकर्ता इंटरफ़ेस के साथ इंटरैक्ट करता है, जैसे UIScrollView के माध्यम से स्क्रॉल करना।


  • डिफ़ॉल्ट - उपयोगकर्ता इंटरफ़ेस के साथ इंटरैक्ट नहीं करता है। इस समय, संसाधन-गहन कार्य को सुरक्षित रूप से पूरा करना संभव है।


  • सामान्य - डिफ़ॉल्ट मोड और ट्रैकिंग मोड को जोड़ता है।

    उपरोक्त कोड के साथ प्रोग्राम चलाने का परिणाम होगा:

जब उपयोगकर्ता यूजर इंटरफ़ेस (यूआई) के साथ इंटरैक्ट करना शुरू करता है, तो मुख्य रन लूप "ट्रैकिंग" मोड में स्विच हो जाता है और इंटरफ़ेस की सुचारूता सुनिश्चित करने के लिए अन्य सभी घटनाओं के प्रसंस्करण को अस्थायी रूप से निलंबित कर देता है। एक बार जब उपयोगकर्ता इंटरफ़ेस के साथ इंटरैक्ट करना बंद कर देता है, तो रन लूप अपने "डिफ़ॉल्ट" मोड पर वापस आ जाता है और हमारा कार्य करना फिर से शुरू कर देता है।

टाइमर

यूजर इंटरफेस के अलावा, लूप टाइमर की कार्यप्रणाली से भी निकटता से जुड़ा हुआ है।


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


 Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { _ in // makeSomething }


टाइमर डिफ़ॉल्ट रूप से डिफ़ॉल्ट मोड में प्रारंभ होता है, इसलिए यदि उपयोगकर्ता इस समय तालिका में स्क्रॉल कर रहा है तो यह काम करना बंद कर सकता है। ऐसा इसलिए है क्योंकि लूप वर्तमान में ट्रैकिंग मोड में है। यही कारण है कि उदाहरण में कोड ठीक से काम नहीं कर सकता है। आप सामान्य मोड में टाइमर जोड़कर इस समस्या को ठीक कर सकते हैं।


 let timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { _ in // makeSomething } RunLoop.main.add(timer, forMode: .common)


साथ ही, हो सकता है कि टाइमर अपेक्षित समय पर सक्रिय न हों या बिल्कुल भी सक्रिय न हों। ऐसा इसलिए है क्योंकि रनलूप केवल प्रत्येक चक्र की शुरुआत में टाइमर की जाँच करता है। यदि रनलूप के इस चरण को पार करने के बाद कोई टाइमर चालू हो जाता है, तो हमें अगले पुनरावृत्ति की शुरुआत तक इसके बारे में पता नहीं चलेगा। साथ ही, रनलूप पर कार्य जितना अधिक समय तक चलेगा, विलंब उतना ही अधिक होगा।


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


 let thread = Thread { let timer = Timer(timeInterval: 1.0, repeats: true) { timer in // makeSomething } RunLoop.current.add(timer, forMode: .default) RunLoop.current.run() } thread.start()


परिणाम

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


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


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