2012-12-29 20 views
19

उद्देश्य-सी में किसी विशिष्ट प्रकार के साथ गणना बनाने का सही तरीका क्या है? NS_ENUM और NS_OPTIONS कैसे काम करते हैं? NS_OPTIONS का उपयोग मास्क के लिए किया जाता है, जैसे NSAutoresizing? धन्यवाद।उद्देश्य-सी गणना, NS_ENUM और NS_OPTIONS

Code from NSObjCRuntime.h 
    #define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type 
    #define NS_OPTIONS(_type, _name) _type _name; enum : _type 
+1

उद्धृत कोड सी ++ के लिए परिभाषित किया गया है। सी परिभाषा है: # परिभाषित NS_ENUM (_type, _name) _type _name; enum –

+0

नीचे मेरा उत्तर जांचना सुनिश्चित करें, पहला जवाब सही है, लेकिन यह NS_OPTIONS और NS_ENUM के बीच पूर्ण अंतर नहीं देता है। – CarmeloS

उत्तर

33

उदाहरण NSHipster से उदाहरण। NS_OPTIONS एक समान तरीके से प्रयोग किया जाता है, लेकिन enums जोकि आमतौर पर होगा के लिए एक सा

बजाय

typedef enum { 
    UITableViewCellStyleDefault, 
    UITableViewCellStyleValue1, 
    UITableViewCellStyleValue2, 
    UITableViewCellStyleSubtitle 
} UITableViewCellStyle; 

या

typedef enum { 
    UITableViewCellStyleDefault, 
    UITableViewCellStyleValue1, 
    UITableViewCellStyleValue2, 
    UITableViewCellStyleSubtitle 
}; 

typedef NSInteger UITableViewCellStyle; 

मुखौटा ऐसा करते हैं:

typedef NS_ENUM(NSInteger, UITableViewCellStyle) { 
    UITableViewCellStyleDefault, 
    UITableViewCellStyleValue1, 
    UITableViewCellStyleValue2, 
    UITableViewCellStyleSubtitle 
}; 

एक उदाहरण NS_OPTIONS enum:

typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) { 
    UIViewAutoresizingNone     = 0, 
    UIViewAutoresizingFlexibleLeftMargin = 1 << 0, 
    UIViewAutoresizingFlexibleWidth  = 1 << 1, 
    UIViewAutoresizingFlexibleRightMargin = 1 << 2, 
    UIViewAutoresizingFlexibleTopMargin = 1 << 3, 
    UIViewAutoresizingFlexibleHeight  = 1 << 4, 
    UIViewAutoresizingFlexibleBottomMargin = 1 << 5 
}; 
+0

लेकिन NS_OPTIONS के बारे में क्या? –

+0

जैसा कि मैंने कहा था, NS_OPTIONS का उपयोग उसी तरह किया जाता है, लेकिन यह बढ़ी हुई enum मानों के बजाय बिट मास्क किए गए मान बनाएगा – wattson12

+0

एक उदाहरण जोड़ा गया – wattson12

8

दोनों के बीच एक अंतर है सिवाय इसके कि वे विभिन्न प्रकार की गणनाओं का अनुमान लगाते हैं।

typedef enum MyOptionType : NSUInteger MyOptionType; enum MyOptionType : NSUInteger { 
    MyOptionType1 = 1 << 0, 
    MyOptionType2 = 1 << 1, 
}; 

typedef enum MyEnumType : NSUInteger MyEnumType; enum MyEnumType : NSUInteger { 
    MyEnumType1 = 1 << 0, 
    MyEnumType2 = 1 << 1, 
}; 
:

typedef NS_OPTIONS(NSUInteger, MyOptionType) { 
    MyOptionType1 = 1 << 0, 
    MyOptionType2 = 1 << 1, 
}; 

typedef NS_ENUM(NSUInteger, MyEnumType) { 
    MyEnumType1 = 1 << 0, 
    MyEnumType2 = 1 << 1, 
}; 

इस कोड को जब मैक्रो Objective-C संकलन में विस्तार कर रहे हैं:

इस मूल कोड है:

जब ऑब्जेक्टिव-सी ++ मोड में संकलित हैं, वे अलग अलग कोड उत्पन्न

यह कोड है जब मैक्रोज़ Objective-C++ संकलन में विस्तारित होते हैं:

typedef NSUInteger MyOptionType; enum : NSUInteger { 
    MyOptionType1 = 1 << 0, 
    MyOptionType2 = 1 << 1, 
}; 

typedef enum MyEnumType : NSUInteger MyEnumType; enum MyEnumType : NSUInteger { 
    MyEnumType1 = 1 << 0, 
    MyEnumType2 = 1 << 1, 
}; 

दो मोड के बीच NS_OPTIONS का अंतर देखें?

HERE IS THE REASON:

वहाँ सी ++ 11 में एक नई सुविधा है, तो आप आप गणना के लिए एक प्रकार घोषणा कर सकते हैं, उससे पहले, प्रकार होल्डिंग गणन enumerations का सबसे बड़ा मान के अनुसार संकलक द्वारा फैसला किया है।

सी ++ 11 में

तो, के बाद से से आप अपने गणना के आकार तय कर सकते हैं, तो आप बिना enums घोषित वास्तव में, उन्हें परिभाषित इस तरह अग्रेषित कर सकते हैं:

//forward declare MyEnumType 
enum MyEnumType: NSInteger 

//use myEnumType 
enum MyEnumType aVar; 

//actually define MyEnumType somewhere else 
enum MyEnumType: NSInteger { 
    MyEnumType1 = 1 << 1, 
    MyEnumType2 = 1 << 2, 
} 

यह सुविधा काम है, और है ऑब्जेक्टिव-सी आयात इस सुविधा है, लेकिन यह एक समस्या लाता है, जब बिटवाइज़ गणना, इस तरह कर रही है:

enum MyEnumType aVar = MyEnumType1 | MyEnumType2; 

इस कोड ++, के बाद से Avar प्रकार NSInteger का माना जाता है लेकिन MyEnumType1 | MyEnumType2 की है सी ++/ऑब्जेक्टिव-सी में संकलन नहीं कर सकते संकलन Ty पे MyEnumType, यह असाइनमेंट बिना किसी प्रकार के कलाकार के प्रदर्शन नहीं कर सकता, सी ++ निहित प्रकार कास्टिंग मना करता है।

इस समय, हम NS_OPTIONS, NS_OPTIONS से ​​पहले सी ++ 11 enum करने के लिए वापस आते हैं, ताकि कोई MyEnumType वास्तव में, MyEnumTypeNSInteger के लिए सिर्फ एक और नाम है की जरूरत है, तो

enum MyEnumType aVar = MyEnumType1 | MyEnumType2; 

की तरह है कि कोड को संकलित होगा , क्योंकि यह NSIntegerNSInteger असाइन कर रहा है।