Swift में Dispatch_once: मुख्य गलतियाँ और सही विकल्प

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

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

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

Swift में Dispatch_once: यह गलती क्यों है और सही सिंगलटन कैसे लिखें

\n\n

यदि आपने कभी सोचा है "Swift में dispatch_once के माध्यम से सिंगलटन कैसे बनाएं?" — तो आप अकेले नहीं हैं। Stack Overflow पर इस प्रश्न को हजारों बार देखा गया है, और कई परियोजनाओं के कोड में आज भी अजीब संरचनाएँ मिलती हैं जो पुराने Objective-C दृष्टिकोण का अनुकरण करने का प्रयास करती हैं। लेकिन अच्छी खबर यह है कि Swift में इसका अधिक सुरुचिपूर्ण और सुरक्षित समाधान है। बुरी खबर: कई डेवलपर्स Objective-C से Swift में आदतों को स्थानांतरित करने का प्रयास करते हुए वही गलतियाँ करते रहते हैं।

\n\n

इस लेख में, हम Swift में dispatch_once का उपयोग करते समय शीर्ष 5 गलतियों पर चर्चा करेंगे, दिखाएंगे कि उनसे कैसे बचें, और सही सिंगलटन का एक तैयार टेम्पलेट देंगे। चलिए शुरू करते हैं!

\n\n

dispatch_once क्या है और Swift में इसकी आवश्यकता क्यों नहीं है?

\n\n

dispatch_once Grand Central Dispatch (GCD) का एक फ़ंक्शन है, जो गारंटी देता है कि कोड का एक ब्लॉक एप्लिकेशन के जीवनकाल में केवल एक बार निष्पादित होगा। Objective-C में, यह थ्रेड-सेफ सिंगलटन बनाने का मानक तरीका था:

\n\n
+ (instancetype)sharedInstance {\n    static MyClass *sharedInstance = nil;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        sharedInstance = [[MyClass alloc] init];\n    });\n    return sharedInstance;\n}
\n\n

हालाँकि, Swift में, संस्करण 1.0 से, dispatch_once उपयोगकर्ता कोड में उपयोग के लिए समर्थित नहीं है। हाँ, आप Dispatch को आयात कर सकते हैं और इसे कॉल करने का प्रयास कर सकते हैं, लेकिन कंपाइलर इसकी अनुमति नहीं देगा। क्यों? क्योंकि Swift में अंतर्निहित साधन हैं जो dispatch_once को अनावश्यक बनाते हैं।

\n\n

Swift में dispatch_once का उपयोग करते समय शीर्ष 5 गलतियाँ

\n\n

गलती 1: सीधे dispatch_once को कॉल करने का प्रयास

\n\n

सबसे आम गलती कुछ इस तरह लिखने का प्रयास है:

\n\n
class MySingleton {\n    static var shared: MySingleton = {\n        let instance = MySingleton()\n        // सेटअप\n        return instance\n    }()\n    \n    private init() {}\n}
\n\n

पहली नज़र में यह काम करता है। लेकिन यह dispatch_once नहीं है। यह केवल एक ग्लोबल वेरिएबल है जो पहली बार एक्सेस करने पर आलसी (lazy) तरीके से इनिशियलाइज़ होता है। Swift ऐसे स्टैटिक प्रॉपर्टी के लिए थ्रेड-सेफ्टी की गारंटी देता है, लेकिन यह dispatch_once के समान नहीं है।

\n\n

यह बुरा क्यों है? क्योंकि आप इनिशियलाइज़ेशन के समय पर नियंत्रण खो देते हैं। यदि आपका सिंगलटन बाहरी संसाधनों (जैसे डेटाबेस या नेटवर्क) पर निर्भर करता है, तो वे अभी तैयार नहीं हो सकते हैं।

\n\n

गलती 2: Objective-C पर रैपर के माध्यम से dispatch_once का उपयोग

\n\n

कुछ डेवलपर्स Swift से dispatch_once को कॉल करने के लिए Objective-C पर एक ब्रिज बनाते हैं:

\n\n
// Objective-C फ़ाइल\n@interface OnceHelper : NSObject\n+ (void)performOnce:(void(^)(void))block;\n@end\n\n@implementation OnceHelper\nstatic dispatch_once_t onceToken;\n+ (void)performOnce:(void(^)(void))block {\n    dispatch_once(&onceToken, block);\n}\n@end
\n\n

फिर Swift में:

\n\n
class MySingleton {\n    static var shared: MySingleton = {\n        var instance: MySingleton!\n        OnceHelper.performOnce {\n            instance = MySingleton()\n        }\n        return instance\n    }()\n}
\n\n

समस्या क्या है? पहला, यह एक पैच है। दूसरा, dispatch_once_t एक ग्लोबल वेरिएबल है, और यदि आप टोकन को रीसेट करना भूल जाते हैं (उदाहरण के लिए, परीक्षण करते समय), तो सिंगलटन पुनः नहीं बनेगा। तीसरा, Apple स्पष्ट रूप से Swift में dispatch_once का उपयोग न करने की सलाह देता है।

\n\n

गलती 3: थ्रेड-सेफ्टी के बारे में भूलना

\n\n

कुछ लोग सिंगलटन इस तरह लिखते हैं:

\n\n
class MySingleton {\n    static var shared: MySingleton?\n    \n    private init() {}\n    \n    static func getInstance() -> MySingleton {\n        if shared == nil {\n            shared = MySingleton()\n        }\n        return shared!\n    }\n}<                

ब्लॉग

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