स्विफ्ट 3.0 में कोई बनाम AnyObject

जब मैंने पहली बार JSON डेटा पार्स करते समय इन दो प्रकार के उपनामों का सामना किया, तो मुझे नहीं पता था कि उन्हें कैसे ठीक से भेद या कार्यान्वित किया जाए। तो, वे क्या हैं? स्विफ्ट में कोई भी और AnyObject दो विशेष प्रकार हैं जिनका उपयोग गैर-विशिष्ट प्रकार के साथ काम करने के लिए किया जाता है।

Apple के स्विफ्ट प्रलेखन के अनुसार,

  • कोई भी किसी भी प्रकार का उदाहरण प्रस्तुत कर सकता है, जिसमें फ़ंक्शन प्रकार और वैकल्पिक प्रकार शामिल हैं।
  • AnyObject किसी भी वर्ग प्रकार के उदाहरण का प्रतिनिधित्व कर सकता है।

ठीक है, सरल पर्याप्त - किसी भी प्रकार का उपयोग सभी प्रकार के लिए किया जाता है, किसी भी प्रकार का उपयोग कक्षा के प्रकारों के लिए किया जाता है, है ना?

यह समझने के लिए कि वे वास्तव में कोड में कैसे व्यवहार करते हैं, मैंने उनके साथ एक खेल के मैदान में खेलने का फैसला किया।

कोई उदाहरण

किसी ने मुझे फंक्शन और नॉन-क्लास टाइप जैसे Int, String और Bool सहित विभिन्न प्रकारों के मिश्रण के साथ काम करने की अनुमति दी। प्रलेखन के अनुसार, इस सरणी में तत्व ऐसे प्रकार हैं जो मूल्य प्रकार हैं, इसलिए सिद्धांत रूप में AnyObject को इन मामलों में काम नहीं करना चाहिए।

इसे सत्यापित करने के लिए मैंने स्ट्रिंग्स और इनट्स को शामिल करने का प्रयास किया, जो कि किसी भी प्रकार का उपयोग करके स्विफ्ट में मूल्य प्रकार हैं।

AnyObjectArray त्रुटि जब संरचना प्रकार शामिल हैं

जैसा कि अपेक्षित था, संकलक ने मुझे यह कहते हुए एक त्रुटि बताई कि तत्व सरणी में किसी भी प्रकार के अनुरूप नहीं थे। पकड़ लिया!

फिर, यह अजीब बात तब हुई जब मैंने संकलक के सुझावों का पालन करने की कोशिश की:

AnyObject के लिए डाली गई तत्व

अभी क्या हुआ?! मैं कैसे InO और Strings पर AnyObject का उपयोग करने में सक्षम था, किसी भी तत्व को AnyObject में स्पष्ट रूप से कास्टिंग करके?

फिर मैंने कंसोल में anyObjectArray छापा।

किसी भी मुद्रण

तत्व हाय स्पष्ट रूप से मेरे लिए एक स्ट्रिंग की तरह लग रहा था, लेकिन इसमें स्विफ्ट में सामान्य स्ट्रिंग मूल्य की तरह उद्धरण नहीं थे!

इसके बाद मैंने प्रत्येक तत्व को किसी भी प्रकार के AnyObject के बजाय उसके वास्तविक प्रकार की जांच के लिए फॉर-इन लूप का उपयोग करके मुद्रित किया।

सबसे पहले, मैंने उपयोग किया है यह देखने के लिए ऑपरेटर है कि तत्व स्विफ्ट संरचना प्रकार हैं या नहीं।

AnyObjectArray में तत्वों के प्रकारों की जाँच करना 1

यह स्ट्रिंग का प्रकार है! फिर इसे AnyObject में कैसे डाला जा सकता है? फिर से, स्ट्रिंग्स इन स्विफ्ट, स्ट्रक्चर हैं, क्लास के प्रकार नहीं। इस प्रकार, सिद्धांत रूप में, मुझे उन्हें AnyObject के रूप में दिखाने में सक्षम नहीं होना चाहिए।

क्या?

मैं पूरी तरह से भ्रमित था, और इसके साथ कुछ और प्रयोग करने का फैसला किया। इस बार मैंने NSNumber और NSString का उपयोग किया, जो प्रत्येक तत्व के प्रकार की जांच करने के लिए Objective-C प्रकार हैं।

AnyObjectArray 2 में तत्वों के प्रकारों की जाँच करना

रुको, हाय भी एक NSString है और संख्यात्मक तत्व NSNumber हैं! और ... वे उद्देश्य-सी में संदर्भ प्रकार हैं! क्या यही कारण था कि हाय, सांत्वना में उस पर उद्धरण नहीं थे? मैंने नीचे कुछ और कोड लिखे हैं, यह देखने के लिए कि क्या मेरी धारणा सही थी।

मुद्रण NSString सरणी और स्ट्रिंग सरणीNSString के रूप में कंसोल में कोई उद्धरण के साथ हाय

की पुष्टि! सरणी में AnyObject के लिए डाले गए तत्व अब श्रेणी के प्रकार हैं- C: NSString और NSNumber।

तो ... क्या वास्तव में हुड के नीचे चल रहा है? मैंने इस विषय पर खुदाई जारी रखी और कोको और ऑब्जेक्टिव-सी (स्विफ्ट 3.0.1) के साथ स्विफ्ट का उपयोग करते हुए दस्तावेज़ से सबसे प्रशंसनीय उत्तर पाया।

ऑब्जेक्टिव-सी के साथ इसकी अंतर्संचालनीयता के हिस्से के रूप में, स्विफ्ट कोको फ्रेमवर्क के साथ काम करने के सुविधाजनक और कुशल तरीके प्रदान करता है। स्विफ्ट स्वचालित रूप से कुछ ऑब्जेक्टिव-सी टाइप्स को स्विफ्ट टाइप्स में कनवर्ट करता है, और कुछ स्विफ्ट टाइप्स ऑब्जेक्टिव-सी टाइप्स को। प्रकार जो कि Objective-C और Swift के बीच परिवर्तित किए जा सकते हैं, को ब्रिजेड प्रकार के रूप में जाना जाता है।
कहीं भी आप एक उद्देश्य ऑब्जेक्ट-सी संदर्भ प्रकार का उपयोग कर सकते हैं, आप इसके बजाय स्विफ्ट मान प्रकार का उपयोग कर सकते हैं। इससे आप संदर्भ प्रकार के कार्यान्वयन पर उपलब्ध कार्यक्षमता का लाभ उठा सकते हैं जो स्विफ्ट कोड में स्वाभाविक है। इस कारण से, आपको लगभग सीधे अपने स्वयं के कोड में ब्रिजेड संदर्भ प्रकार का उपयोग करने की आवश्यकता नहीं होनी चाहिए। वास्तव में, जब स्विफ्ट कोड ऑब्जेक्टिव-सी एपीआई आयात करता है, तो आयातक अपने संबंधित मूल्य प्रकारों के साथ ऑब्जेक्टिव-सी संदर्भ प्रकारों को बदलता है। इसी तरह, जब ऑब्जेक्टिव-सी कोड स्विफ्ट एपीआई का आयात करता है, तो आयातक स्विफ्ट मूल्य प्रकारों को उनके संबंधित उद्देश्य-सी संदर्भ प्रकारों के साथ बदल देता है। "

दूसरे शब्दों में, कम्पाइलर इस तरह के ऑटोमैटिक कन्वर्सेशन से निपटने में लचीला है और हमारे ऐप को आसानी से क्रैश होने से बचाता है। प्रतिभाशाली!

तो हम वास्तव में AnyObject का उपयोग कब करते हैं? जैसा कि Apple के प्रलेखन में कहा गया है, AnyObject का उपयोग उन वस्तुओं के साथ काम करने के लिए किया जा सकता है जो कक्षा से प्राप्त होते हैं लेकिन वह एक सामान्य रूट क्लास साझा नहीं करता है।

लेकिन क्या हमारे कोड में इसका उपयोग करना बिल्कुल आवश्यक है?

इस सवाल का मेरा जवाब है: नहीं।

Apple कहता है:

स्विफ्ट 3 में, ऑब्जेक्टिव-सी में आईडी प्रकार अब स्विफ्ट में किसी भी प्रकार के लिए मैप करता है, जो किसी भी प्रकार के मूल्य का वर्णन करता है, चाहे एक वर्ग, एनम, संरचना, या किसी अन्य स्विफ्ट प्रकार। यह परिवर्तन स्विफ्ट में ऑब्जेक्टिव-सी एपीआई को अधिक लचीला बनाता है, क्योंकि स्विफ्ट-परिभाषित मूल्य प्रकारों को ऑब्जेक्टिव-सी एपीआई में पारित किया जा सकता है और स्विफ्ट प्रकारों के रूप में निकाला जा सकता है, मैनुअल "बॉक्स" प्रकारों की आवश्यकता को समाप्त करता है।
ये लाभ संग्रह को भी बढ़ाते हैं: उद्देश्य-सी संग्रह प्रकार NSArray, NSDictionary, और NSSet, जो पहले केवल AnyObject के तत्वों को स्वीकार करते थे, अब किसी भी प्रकार के तत्वों को पकड़ सकते हैं। हैशड कंटेनर के लिए, जैसे कि डिक्शनरी और सेट, एक नया प्रकार एनीहैशबेल है जो स्विफ्ट हस्बी प्रोटोकॉल के अनुरूप किसी भी प्रकार के मूल्य को पकड़ सकता है।

ऐसा लगता है कि AnyObject के उपयोग की आवश्यकता के बिना स्विफ्ट 3 में इन दो भाषाओं को पाटने में कोई भी अकेला पूरी तरह से ठीक काम करता है!

तो इन परिवर्तनों के पीछे अंतिम तर्क क्या था?

अपने शब्दों में, Apple बताते हैं:

पिछले संस्करणों की तुलना में अधिक शक्तिशाली तरीके से ऑब्जेक्टिव-सी एपीआई के साथ स्विफ्ट 3 इंटरफेस। उदाहरण के लिए, स्विफ्ट 2 ने स्विफ्ट में किसी भी प्रकार के ऑब्जेक्टिव-सी में आईडी टाइप को मैप किया है, जो सामान्य रूप से केवल क्लास के प्रकारों के मूल्यों को पकड़ सकता है। स्विफ्ट 2 ने कुछ उल्लिखित मान प्रकारों जैसे कि स्ट्रिंग, एरे, डिक्शनरी, सेट और कुछ नंबरों के लिए किसी भी सुविधा के रूप में AnyObject को अंतर्निहित रूपांतरण प्रदान किया ताकि देशी स्विफ्ट प्रकारों को कोको एपीआई के साथ आसानी से इस्तेमाल किया जा सके, जो NSString, NSArray की अपेक्षा करता है। या फाउंडेशन से अन्य कंटेनर कक्षाएं। ये रूपांतरण बाकी भाषा के साथ असंगत थे, जिससे यह समझना मुश्किल हो गया कि वास्तव में एक AnyObject के रूप में क्या उपयोग किया जा सकता है, जिसके परिणामस्वरूप बग हो सकते हैं।

हालांकि, एक जोर देकर कहा जाएगा कि हम आईओएस डेवलपर्स को हमेशा कोड में प्रकारों का उपयोग करने के मामले में यथासंभव विशिष्ट होने की आवश्यकता है।

वास्तव में, Apple अनुशंसा करता है:

किसी भी और AnyObject का उपयोग केवल तब करें जब आपको स्पष्ट रूप से उनके द्वारा प्रदान किए जाने वाले व्यवहार और क्षमताओं की आवश्यकता हो। अपने कोड में काम करने की अपेक्षा के प्रकारों के बारे में विशिष्ट होना हमेशा बेहतर होता है।

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

मुझे उम्मीद है कि इस ब्लॉग पोस्ट ने किसी भी और AnyObject को स्पष्ट करने में आपके कई भयानक डेवलपर्स की मदद की। उद्देश्य-सी समर्थित एपीआई के साथ काम करते समय स्विफ्ट 3 में किसी भी आत्मविश्वास का उपयोग करें।

पढ़ने और खुश कोडिंग के लिए धन्यवाद!