शुरुआती Swift डेवलपर्स की शीर्ष गलतियाँ: उन्नत स्तर

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

शुरुआती Swift डेवलपर्स की शीर्ष गलतियाँ: उन्नत स्तर

\n\n

जब आप SwiftUI पर सरल स्क्रीन लिखने से कस्टम आर्किटेक्चर वाले जटिल मल्टीथ्रेडेड एप्लिकेशन बनाने की ओर बढ़ते हैं, तो छिपी हुई समस्याओं की संख्या तेजी से बढ़ जाती है। Swift का बुनियादी सिंटैक्स सीखने के बाद, कई डेवलपर खुद को प्रोडक्शन के लिए तैयार मानते हैं, लेकिन वे गंभीर गलतियाँ करते हैं जो मेमोरी लीक, अस्थिर प्रदर्शन और मुश्किल से पकड़ में आने वाले बग का कारण बनती हैं। इस लेख में, हम चार श्रेणियों की गलतियों का विश्लेषण करेंगे जो मध्य-स्तर के डेवलपर्स में सबसे अधिक पाई जाती हैं।

\n\n

1. क्लोजर में मेमोरी लीक: केवल [weak self] ही नहीं

\n\n

सबसे आम गलती यह है कि [weak self] का उपयोग यह समझे बिना किया जाता है कि वास्तव में इसकी आवश्यकता कब है। कई डेवलपर जहाँ भी क्लोजर होता है, वहाँ weak self लगा देते हैं, जिससे ऑब्जेक्ट समय से पहले नष्ट हो जाते हैं। या, इसके विपरीत, वे गैर-स्पष्ट स्थानों में मजबूत संदर्भ चक्र (strong reference cycles) के बारे में भूल जाते हैं।

\n\n

सामान्य गलती: क्लोजर के अंदर ऑब्जेक्ट पर एक मजबूत संदर्भ बनाना, जिसे वही ऑब्जेक्ट संग्रहीत करता है।

\n\n
class NetworkManager {\n    var onCompletion: (() -> Void)?\n    \n    func fetchData() {\n        // गलती: क्लोजर self को मजबूती से कैप्चर करता है\n        onCompletion = {\n            self.updateUI()\n        }\n    }\n    \n    func updateUI() {\n        print("UI अपडेट किया गया")\n    }\n}
\n\n

सही समाधान: ऑब्जेक्ट के जीवनकाल के आधार पर [weak self] या [unowned self] का उपयोग करें।

\n\n
class NetworkManager {\n    var onCompletion: (() -> Void)?\n    \n    func fetchData() {\n        onCompletion = { [weak self] in\n            guard let self = self else { return }\n            self.updateUI()\n        }\n    }\n    \n    func updateUI() {\n        print("UI अपडेट किया गया")\n    }\n}
\n\n

उन्नत बारीकी: [unowned self] से सावधान रहें। यदि ऑब्जेक्ट मुक्त हो जाता है और क्लोजर को कॉल किया जाता है, तो एप्लिकेशन क्रैश हो जाएगा। unowned का उपयोग केवल तभी करें जब आप 100% आश्वस्त हों कि ऑब्जेक्ट क्लोजर से अधिक समय तक जीवित रहेगा।

\n\n

2. async/await और एक्टर के साथ गलत काम

\n\n

Swift 5.5 में Structured Concurrency के आने के बाद, कई डेवलपर ने async/await का सक्रिय रूप से उपयोग करना शुरू कर दिया, लेकिन MainActor और Sendable के बारे में भूल गए। इससे race conditions और बैकग्राउंड थ्रेड से UI अपडेट होने की समस्या होती है।

\n\n

सामान्य गलती: एक एसिंक्रोनस फ़ंक्शन को कॉल करना जो मुख्य थ्रेड पर चलना चाहिए, बिना स्पष्ट रूप से @MainActor निर्दिष्ट किए।

\n\n
class ViewModel: ObservableObject {\n    @Published var data: [String] = []\n    \n    // गलती: फ़ंक्शन @MainActor से चिह्नित नहीं है\n    func loadData() async {\n        let result = await fetchFromNetwork()\n        // यह बैकग्राउंड थ्रेड पर निष्पादित हो सकता है!\n        self.data = result\n    }\n    \n    func fetchFromNetwork() async -> [String] {\n        try? await Task.sleep(nanoseconds: 1_000_000_000)\n        return ["Item1", "Item2"]\n    }\n}
\n\n

सही समाधान: UI अपडेट करने वाले फ़ंक्शन के लिए @MainActor का उपयोग करें।

\n\n
class ViewModel: ObservableObject {\n    @Published var data: [String] = []\n    \n    @MainActor // अब यह गारंटी है कि मुख्य थ्रेड पर निष्पादित होगा\n    func loadData() async {\n        let result = await fetchFromNetwork()\n        self.data = result\n    }\n    \n    func fetchFromNetwork() async -> [String] {\n        try? await Task.sleep(nanoseconds: 1_000_000_000)\n        return ["Item1", "Item2"]\n    }\n}
\n\n

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

\n\n

3. Race Conditions में

ब्लॉग

पुस्तक अनुशंसाएँ