बैकग्राउंड थ्रेड हर iOS डेवलपर का दर्द क्यों हैं?
\n\nकल्पना करें: आप इंटरनेट से फ़ोटो डाउनलोड करने के लिए एक ऐप लिख रहे हैं। सब कुछ पूरी तरह से काम कर रहा है... जब तक उपयोगकर्ता "डाउनलोड" बटन नहीं दबाता। स्क्रीन हैंग हो जाती है, ऐप "लैग" करता है, और कुछ सेकंड के बाद iOS आपकी प्रक्रिया को मार देता है। परिचित लगता है?
\n\nसमस्या यह है कि सभी ऑपरेशन डिफ़ॉल्ट रूप से मुख्य थ्रेड (main thread) पर निष्पादित होते हैं। और मुख्य थ्रेड UI रेंडर करने के लिए जिम्मेदार है - यदि आप इसे किसी लंबे कार्य से ब्लॉक करते हैं, तो इंटरफ़ेस टच पर प्रतिक्रिया देना बंद कर देगा। समाधान? Swift में background thread (बैकग्राउंड थ्रेड) का उपयोग करें।
\n\nइस लेख में, हम वास्तविक उदाहरणों के साथ बैकग्राउंड थ्रेड के साथ काम करना समझेंगे। आप GCD, OperationQueue और Swift 5.5+ के नए async/await के बारे में जानेंगे। चलिए शुरू करते हैं!
\n\nSwift में थ्रेड (thread) क्या है?
\n\nथ्रेड एक हल्की प्रक्रिया है जो प्रोग्राम का कोड निष्पादित करती है। iOS ऐप में एक मुख्य थ्रेड (main thread) और कई बैकग्राउंड थ्रेड होते हैं। मुख्य थ्रेड UI का ध्यान रखता है: स्क्रीन अपडेट करना, जेस्चर प्रोसेस करना, एनिमेशन। इंटरफ़ेस से संबंधित सब कुछ केवल मुख्य थ्रेड पर होना चाहिए।
\n\nबैकग्राउंड थ्रेड (background threads) की आवश्यकता निम्न के लिए होती है:
\n- \n
- नेटवर्क से डेटा डाउनलोड करना \n
- फ़ाइलों के साथ काम करना (पढ़ना/लिखना) \n
- जटिल गणनाएँ (इमेज प्रोसेसिंग, एन्क्रिप्शन) \n
- डेटाबेस के साथ काम करना \n
यदि आप बैकग्राउंड थ्रेड से UI अपडेट करने का प्रयास करते हैं - तो ऐप क्रैश हो जाएगा, या आप इंटरफ़ेस का अजीब व्यवहार देखेंगे।
\n\nGCD (Grand Central Dispatch) — क्लासिक तरीका
\n\nGrand Central Dispatch (GCD) iOS/macOS में निर्मित थ्रेड प्रबंधन के लिए एक निम्न-स्तरीय लाइब्रेरी है। यह क्यू (queues) के माध्यम से काम करती है: आप क्यू में एक कार्य रखते हैं, और सिस्टम स्वयं तय करता है कि इसे किस थ्रेड पर निष्पादित करना है।
\n\nDispatchQueue.main — मुख्य थ्रेड
\nयदि आपको मुख्य थ्रेड पर कोड निष्पादित करने की आवश्यकता है (उदाहरण के लिए, UILabel अपडेट करना), तो उपयोग करें:
\n\nDispatchQueue.main.async {\n self.label.text = "डाउनलोड पूर्ण!"\n}\n\nDispatchQueue.global() — बैकग्राउंड थ्रेड
\nबैकग्राउंड कार्यों के लिए ग्लोबल क्यू का उपयोग करें:
\n\nDispatchQueue.global(qos: .background).async {\n // भारी काम\n let imageData = try? Data(contentsOf: url)\n \n // UI के लिए मुख्य थ्रेड पर वापस आएँ\n DispatchQueue.main.async {\n self.imageView.image = UIImage(data: imageData!)\n }\n}\n\nपैरामीटर qos (Quality of Service) कार्य की प्राथमिकता निर्धारित करता है:
- \n
.userInteractive— सबसे उच्च, UI के लिए \n .userInitiated— उपयोगकर्ता परिणाम की प्रतीक्षा करता है \n .utility— लंबे कार्य (फ़ाइल डाउनलोड) \n .background— कम प्राथमिकता (सिंक्रोनाइज़ेशन, बैकअप) \n
OperationQueue — अधिक नियंत्रण
\n\nOperationQueue अतिरिक्त क्षमताओं के साथ GCD के ऊपर एक लेयर है:
\n- \n
- कार्यों को रद्द करना \n
- कार्यों के बीच निर्भरताएँ \n
- समानांतर थ्रेड की अधिकतम संख्या \n
एकाधिक इमेज डाउनलोड करने का उदाहरण:
\n\nlet queue = OperationQueue()\nqueue.maxConcurrentOperationCount = 2 // एक साथ अधिकतम 2 कार्य\n\nlet operation1 = BlockOperation {\n // पहली इमेज डाउनलोड करना\n sleep(2)\n print("फ़ोटो 1 डाउनलोड हुई")\n}\n\nlet operation2 = BlockOperation {\n // दूसरी इमेज डाउनलोड करना\n sleep(3)\n print("फ़ोटो 2 डाउनलोड हुई")\n}\n\n// operation2 operation1 के पूर्ण होने के बाद ही शुरू होगा\noperation2.addDependency(operation1)\n\nqueue.addOperations([operation1, operation2], waitUntilFinished: false)\n\nयह तब सुविधाजनक होता है जब आपको कार्यों को सख्त क्रम में या संसाधन सीमाओं के साथ निष्पादित करने की आवश्यकता होती है।
\n\nआधुनिक async/await (Swift 5.5+)
\n\nSwift 5.5 से शुरू करते हुए, Ap