2009-06-03 13 views
47

में आगे बढ़ने के लिए मुझे एक उद्देश्य-सी कार्यक्रम में enum दृश्यता में परेशानी हो रही है। मेरे पास दो शीर्षलेख फ़ाइलें हैं, और एक typedef enum परिभाषित करता है। एक और फ़ाइल को typedef 'डी प्रकार का उपयोग करने की आवश्यकता है।उद्देश्य-सी

सीधे सी में, मैं बस #include अन्य हेडर फाइल है, लेकिन ऑब्जेक्टिव-सी में, यह हेडर फाइल के बीच #import उपयोग करने के लिए नहीं है, बजाय आगे @class घोषणाओं का उपयोग कर के रूप में की जरूरत अनुशंसा की जाती है जाएगा। हालांकि, मैं समझ नहीं सकता कि एक गणना प्रकार कैसे आगे बढ़ाना है।

मुझे .m कार्यान्वयन फ़ाइल को छोड़कर वास्तविक गणना मूल्यों की आवश्यकता नहीं है, जहां मैं सुरक्षित रूप से #import दूर कर सकता हूं। तो मैं हेडर में पहचाने जाने के लिए typedef enum कैसे प्राप्त कर सकता हूं?

+0

हाल उत्तर के लिए (स्विफ्ट 3, 2017) देखो मेरे जवाब पर http://stackoverflow.com/a/42009056/342794 – lal

उत्तर

18

आगे बढ़ें और #import का उपयोग करें। जब संभव हो तो @class का उपयोग करने का एकमात्र कारण यह है कि यह आपके कोड को संकलित करने के लिए थोड़ा तेज़ बनाता है। हालांकि, #import के साथ एक .h फ़ाइल में कोई समस्या नहीं है। वास्तव में, आपको एक और कक्षा का विस्तार करते समय ऐसा करने की ज़रूरत है।

+1

क्या #import का उपयोग किए बिना उपरोक्त संभव है? बस 'typedef int EnumName' करने के बारे में क्या? –

+1

मुझे ऐसा नहीं लगता है। जीएस के उत्तर में लिंक देखें: http://stackoverflow.com/questions/71416/forward-declaring-an-enum-in-c –

+0

#import संकलन के साथ मिनटों की आवश्यकता है, और वैसे भी कुछ वायर्ड चीज है। –

0

आपको या तो #import या तो उन्हें एक अलग हेडर फ़ाइल बनाना होगा जिसमें केवल typedef है। शीर्षलेख में हेडर फ़ाइलों को आयात नहीं करना संकलन को तेज बनाता है, लेकिन कुछ और नहीं बदलता है।

Why doesn't C++ support forward declaration of enums?

16

अपने प्रश्न का उत्तर या तो आगे जाना है और typedef हेडर फाइल को आयात या enum प्रकार के बजाय NSInteger की तरह एक सामान्य प्रकार का उपयोग करने के लिए है।

हालांकि, संकलन गति की तुलना में हेडर फ़ाइल आयात न करने का अधिक कारण है।

हेडर फ़ाइल आयात नहीं करने से बाहरी कक्षाओं में आपकी अनजान पहुंच भी कम हो जाती है।

उदाहरण के लिए, कहें कि आपके पास एक ट्रैकफ़ाइल चेंज क्लास है जो एक विशिष्ट फ़ाइल में परिवर्तन के लिए फ़ाइल सिस्टम को ट्रैक करती है, और आपके पास एक कैशफ़ाइल क्लास है जो फ़ाइल से कैश किए गए डेटा को संग्रहीत करती है। उत्तरार्द्ध एक निजी ivar प्रकार TrackFileChanges * का उपयोग कर सकता है, लेकिन कैशफ़ाइल के उपयोग के लिए, यह केवल एक कार्यान्वयन विवरण है (आदर्श रूप से, ivar नए रनटाइम का उपयोग करके एक निजी संपत्ति के साथ स्वत: जेनरेट किया जाएगा, लेकिन यह संभव नहीं है यदि आप ' पुराने रन टाइम का उपयोग कर रहे हैं)।

तो क्लाइंट जो #import "CachedFile.h" को संभवतः TrackFileChanges.h तक पहुंच की आवश्यकता नहीं है या नहीं चाहते हैं। और यदि वे करते हैं, तो उन्हें इसे स्वयं भेजकर स्पष्ट कर देना चाहिए। CachedFile.h में #import "TrackFileChanges.h" के @class TrackFileChanges instea का उपयोग करके आप encapsulation में सुधार करते हैं।

लेकिन सभी ने कहा कि, दूसरी हेडर फ़ाइल से हेडर फ़ाइल आयात करने के साथ कुछ भी नहीं है यदि दूसरा हेडर सभी क्लाइंट्स को पहले एक्सपोज़ करना चाहता है। उदाहरण के लिए, हेडर फाइलें जो वर्गों को घोषित करती हैं उन्हें सीधे सरलीकृत हेडर फाइलों में आयात करने की आवश्यकता होती है, और प्रोटोकॉल घोषित करने वाली हेडर फाइलें सीधे आयात की जा सकती हैं (हालांकि आप इससे बचने के लिए @protocol एबीसी का उपयोग कर सकते हैं)।

4

आप संकलक एक्सटेंशन का उपयोग ठीक हैं, तो आप बजना में इस आदेश का उपयोग कर सकता:

enum Enum; 
typedef enum Enum Enum2; 

void f(Enum2); // ok. it sees this type's true name. 

enum Enum { 
    E_1 
}; 

// ok. now its declaration is visible and we can use it. 

void f(Enum2 e) { 

} 

नोट: यह एक -Wpedantic चेतावनी ट्रिगर किया जाएगा।


यदि आप सी ++ 11 का उपयोग कर रहे हैं, तो आपको अपने enums का उपयोग करना चाहिए, जो घोषित करने के लिए सुरक्षित हैं - उदा। enum class Enum:uint8_t; (एक कंपाइलर एक्सटेंशन नहीं)। ;

+1

आप इस उत्तर को इस प्रकार सरल बना सकते हैं: 'टाइपिफ एनम एनम एनम;' फिर बस अपनी विधि परिभाषा और घोषणा में एनम का उपयोग करें। –

15

सबसे हाल का रास्ता (स्विफ्ट 3 मई 2017) को अग्रेषित करने के उद्देश्य-सी में enum (NS_ENUM/NS_OPTION) घोषित निम्न का उपयोग करने के लिए है:

// Forward declaration for XYZCharacterType in other header say XYZCharacter.h 
typedef NS_ENUM(NSUInteger, XYZCharacterType); 


// Enum declaration header: "XYZEnumType.h" 
#ifndef XYZCharacterType_h 
#define XYZCharacterType_h 

typedef NS_ENUM(NSUInteger, XYZEnumType) { 
    XYZCharacterTypeNotSet, 
    XYZCharacterTypeAgent, 
    XYZCharacterTypeKiller, 
}; 

#endif /* XYZCharacterType_h */` 
+1

ने स्विफ्ट 3 – stringRay2014

+3

के साथ मेरे लिए काम किया है आजकल स्वीकार्य उत्तर – citxx

+1

होना चाहिए, मैंने कल पुराने उद्देश्य सी कोड को साफ करने के तरीके के रूप में टाइपिफ़ एनएस_एनयूएम को देखना शुरू कर दिया - और यह उत्तर मेरे लिए काम करता था। – Greg