ऑब्जेक्टिव-सी में स्थिरांक बनाने का सबसे अच्छा तरीका क्या है


156

मैं सीखने के उद्देश्यों के लिए Reddit क्लाइंट बना रहा हूं। मुझे इसमें स्थिरांक के साथ एक फ़ाइल की आवश्यकता है। मैं फ़ाइल में फ़ाइल आयात करने के बारे में सोच रहा था Reddit-Prefix.pchताकि सभी फ़ाइलों को निरंतर उपलब्ध हो सके। क्या यह चीजों को करने का एक अच्छा तरीका है? इसके अलावा, मैंने अपना शोध किया है और स्थिरांक बनाने के कई तरीके पाए हैं, लेकिन मुझे नहीं पता कि किसका उपयोग करना है:

  • #define मैक्रो
  • const
  • static const
  • extern const
  • enum

तो पसंदीदा तरीका कौन सा है? अधिवेशन क्या है? मुझे पता है कि "यह निर्भर करता है" लेकिन मेरा प्रश्न अधिक विशेष रूप से है: उन समाधानों में से प्रत्येक के लिए उपयोग के मामले क्या हैं?

इसके अलावा, यदि उपयोग करते हैं extern const, तो क्या मुझे फ़ाइल आयात करने की आवश्यकता है, या फ़ाइल आयात किए बिना स्थिरांक वैश्विक रूप से उपलब्ध होंगे?

एक चीज जो मैं तार्किक रूप से निष्कर्ष निकाल सकता हूं, वह enumयह है कि कस्टम त्रुटि डोमेन जैसी किसी चीज़ को परिभाषित करते समय सबसे अच्छा विकल्प क्या है (क्या मैं वास्तव में सही हूं)। लेकिन दूसरों के बारे में क्या?


stackoverflow.com/questions/11153156/… कृपया इस लिंक पर जाएँ ... आपका समाधान इस पोस्ट में है
उपयोगकर्ता 1531343

3
@ भविकमा: यह दो विशिष्ट समाधानों के विपरीत एक संकीर्ण प्रश्न है।
पीटर होसी

के लिए - स्थैतिक कास्ट, #
डेफिन

enumअभिन्न मूल्यों के लिए ही उपयोगी है। #defineऔर स्थिरांक कोई भी डेटा प्रकार हो सकता है।
रद्दी

const, static constऔर extern constगुंजाइश के अलावा सभी समान हैं। तो वास्तव में केवल तीन विकल्प हैं।
रम्डी

जवाबों:


385

पहला प्रश्न यह है कि आप अपने स्थिरांक को किस दायरे में रखना चाहते हैं, जो वास्तव में दो प्रश्न हैं:

  • क्या ये स्थिरांक एक एकल वर्ग के लिए विशिष्ट हैं, या क्या यह समझ में नहीं आता है कि ये सभी अनुप्रयोग में हैं?
  • यदि वे वर्ग-विशिष्ट हैं, तो क्या वे कक्षा के ग्राहकों द्वारा उपयोग किए जाते हैं, या केवल कक्षा के भीतर ही हैं?

यदि वे एकल वर्ग के लिए विशिष्ट और आंतरिक हैं, तो उन्हें static const.m फ़ाइल के शीर्ष पर घोषित करें , जैसे:

static NSString *const MyThingNotificationKey = @"MyThingNotificationKey";

यदि वे एक ही वर्ग से संबंधित हैं, लेकिन सार्वजनिक / अन्य वर्गों द्वारा उपयोग किया जाना चाहिए, उन्हें externहेडर के रूप में घोषित करें और उन्हें परिभाषित करें:

//.h
extern NSString *const MyThingNotificationKey;

//.m
NSString *const MyThingNotificationKey = @"MyThingNotificationKey";

यदि उन्हें वैश्विक होना चाहिए, तो उन्हें हेडर में घोषित करें और उन्हें उसी मॉड्यूल में परिभाषित करें, विशेष रूप से उन स्थिरांक के लिए।

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

क्यों नहीं #define?

पुराना उत्तर है "मैक्रोज़ के पास टाइप की जानकारी नहीं है", लेकिन कंपाइलर्स आज सभी प्रकार के चेक-इन शाब्दिक (मैक्रोज़ का विस्तार) के साथ-साथ चर के बारे में बहुत स्मार्ट हैं।

आधुनिक उत्तर इसलिए है क्योंकि डिबगर को आपके मैक्रोज़ के बारे में पता नहीं होगा। यदि आप एक मैक्रो है [myThing addObserver:self forKey:MyThingNotificationKey]तो आप डिबगर कमांड में नहीं कह सकते MyThingNotificationKey; डीबगर केवल इसके बारे में जान सकता है यदि यह एक चर है।

क्यों नहीं enum?

खैर, असभ्य ने मुझे टिप्पणियों में इसे हराया: enumकेवल पूर्णांक स्थिरांक को परिभाषित कर सकता है। सीरियल पहचानकर्ता संख्या, बिट-मास्क, चार-बाइट कोड आदि जैसी चीजें।

उन उद्देश्यों के लिए, enumमहान है और आपको इसका पूरा उपयोग करना चाहिए। (इससे भी बेहतर, और मैक्रोज़ का उपयोग करेंNS_ENUMNS_OPTIONS ।) अन्य चीजों के लिए, आपको कुछ और उपयोग करना चाहिए ; enumपूर्णांक के अलावा कुछ नहीं करता है।

और अन्य प्रश्न

मैं सभी फाइलों को उपलब्ध कराने के लिए Reddit-Prefix.pch फ़ाइल में फ़ाइल आयात करने के बारे में सोच रहा था। क्या यह चीजों को करने का एक अच्छा तरीका है?

शायद हानिरहित, लेकिन शायद अत्यधिक। अपने स्थिरांक शीर्षकों को आयात करें जहाँ आपको उनकी आवश्यकता है।

उन समाधानों में से प्रत्येक के लिए उपयोग के मामले क्या हैं?

  • #define: बहुत सीमित। मैं ईमानदारी से यकीन नहीं कर रहा हूँ कि अब स्थिरांक के लिए इसका उपयोग करने का एक अच्छा कारण है।
  • const: स्थानीय स्थिरांक के लिए सर्वश्रेष्ठ। इसके अलावा, आपको इसे एक हेडर में घोषित एक के लिए उपयोग करना होगा और अब परिभाषित कर रहा है।
  • static const: फ़ाइल-विशिष्ट (या वर्ग-विशिष्ट) स्थिरांक के लिए सर्वश्रेष्ठ।
  • extern const: हेडर में स्थिरांक निर्यात करते समय आपको इसका उपयोग करना चाहिए।

इसके अलावा, यदि उपयोग करते हैं extern const, तो क्या मुझे फ़ाइल आयात करने की आवश्यकता है, या फ़ाइल आयात किए बिना स्थिरांक वैश्विक रूप से उपलब्ध होंगे?

आपको फ़ाइल को आयात करने की आवश्यकता है, या तो प्रत्येक फ़ाइल में जहां आप उसका उपयोग करते हैं या उपसर्ग शीर्षक में।


3
क्यों उपयोग नहीं कर static NSString *constमें .hफ़ाइल पूरी तरह?
इयूलियन ओनोफ्रेई

3
@IulianOnofrei: आप कर सकते हैं, अगर यह एक आवेदन में है और एक रूपरेखा नहीं है। यदि आप करते हैं static NSString *const foo = @"foo";, तो आपका हेडर यह निर्धारित करता है कि स्ट्रिंग क्या है, और यह हर जगह एक ही होना चाहिए - यदि आप कभी भी स्ट्रिंग बदलते हैं और विभिन्न पार्टियां हेडर के विभिन्न संस्करणों का उपयोग एक अलग स्ट्रिंग के साथ करती हैं, तो स्ट्रिंग्स रन से मेल नहीं खाएंगे। समय। किसी फ़्रेमवर्क में, आप केवल प्रतीक तक पहुँच प्रदान करना चाहते हैं, और फ़्रेमवर्क उस प्रतीक के सही मूल्य का एकमात्र स्रोत है, इसलिए सभी को एक ही स्थान से एक ही स्ट्रिंग प्राप्त हो रही है। जो externआपको मिलता है।
पीटर होसी

#defineS पर अतिरिक्त ध्यान दें : उन्हें स्मृति में समान पते की गारंटी नहीं है (वे कैसे घोषित किए गए हैं इसके आधार पर, वे हर बार उपयोग किए जाने पर एक नया उदाहरण आवंटित कर सकते हैं), इसलिए उपयोग myObject == MyDefineकरना हमेशा अपेक्षा के अनुरूप काम नहीं करेगा, लेकिन myObject == MyStaticConstहोगा।
बेन लेगियरियो

क्या इसके static NSString *constबजाय वर्तनी में समझ में आता है static NSString const*?? कोई मतभेद!
kokos8998

@ kokos8998 से फर्क पड़ता है? हाँ यह करता है। static NSString const *के रूप में ही है static const NSString *और इसका मतलब है "एक निरंतर NSString के लिए एक (परिवर्तनीय) सूचक" - जो यहाँ थोड़ा बेकार है क्योंकि NSString पहले से ही अपरिवर्तनीय है। आप केवल वही चाहते हैं static NSString * const- जो "NSString के लिए एक निरंतर पॉइंटर" है
डेविड

8

FOUNDATION_EXPORT

नींव से परिभाषित करने की FOUNDATION_EXPORTतुलना में थोड़ा अधिक संगतता के लिए उपयोग करने पर विचार करें externऔर C, C ++ और Win32 के लिए संगत प्रारूपों का संकलन करता है।

NSObjCRuntime.h में परिभाषित किया गया है

#if defined(__cplusplus)
#define FOUNDATION_EXTERN extern "C"
#else
#define FOUNDATION_EXTERN extern
#endif

#if TARGET_OS_WIN32

    #if defined(NSBUILDINGFOUNDATION)
        #define FOUNDATION_EXPORT FOUNDATION_EXTERN __declspec(dllexport)
    #else
        #define FOUNDATION_EXPORT FOUNDATION_EXTERN __declspec(dllimport)
    #endif

    #define FOUNDATION_IMPORT FOUNDATION_EXTERN __declspec(dllimport)

#else
    #define FOUNDATION_EXPORT  FOUNDATION_EXTERN
    #define FOUNDATION_IMPORT FOUNDATION_EXTERN
#endif
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.