В чем разница между ns_enum и ns_options? -- ios поле с участием objective-c поле с участием cocoa пол Связанный проблема

What is the difference between NS_ENUM and NS_OPTIONS?


32
vote

проблема

русский

i предварительно назначил следующий код с помощью clang в xcode5.

 <код> typedef NS_ENUM(NSInteger, MyStyle) {     MyStyleDefault,     MyStyleCustom };  typedef NS_OPTIONS(NSInteger, MyOption) {     MyOption1 = 1 << 0,     MyOption2 = 1 << 1, };   

и получил это.

 <код> typedef enum MyStyle : NSInteger MyStyle; enum MyStyle : NSInteger {     MyStyleDefault,     MyStyleCustom };  typedef enum MyOption : NSInteger MyOption; enum MyOption : NSInteger {     MyOption1 = 1 << 0,     MyOption2 = 1 << 1, };   

Я знаю, что ns_options предназначен для растровой маски, но есть ли какие-либо технические различия? Или это только для Конвенции именования?

Редактировать

Согласно определению NS_OPTions, это, вероятно, для совместимости компилятора. (Специально для компилятора C ++)

 <код> // In CFAvailability.h // Enums and Options #if (__cplusplus && __cplusplus >= 201103L && (__has_extension(cxx_strong_enums) || __has_feature(objc_fixed_enum))) || (!__cplusplus && __has_feature(objc_fixed_enum))   #define CF_ENUM(_type, _name) enum _name : _type _name; enum _name : _type   #if (__cplusplus)     #define CF_OPTIONS(_type, _name) _type _name; enum : _type   #else     #define CF_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type   #endif #else   #define CF_ENUM(_type, _name) _type _name; enum   #define CF_OPTIONS(_type, _name) _type _name; enum #endif   

___ Значение CPLUSPLUS в Clang IS 199711 года, и я не могу проверить, что это точно для того, чтобы.

Английский оригинал

I preprocessed following code with clang in Xcode5.

typedef NS_ENUM(NSInteger, MyStyle) {     MyStyleDefault,     MyStyleCustom };  typedef NS_OPTIONS(NSInteger, MyOption) {     MyOption1 = 1 << 0,     MyOption2 = 1 << 1, }; 

And got this.

typedef enum MyStyle : NSInteger MyStyle; enum MyStyle : NSInteger {     MyStyleDefault,     MyStyleCustom };  typedef enum MyOption : NSInteger MyOption; enum MyOption : NSInteger {     MyOption1 = 1 << 0,     MyOption2 = 1 << 1, }; 

I know NS_OPTIONS is for a bitmask, but is there any technical differences? Or this is just for naming convention?

EDIT

According to the definition of NS_OPTIONS, it's probably for compiler compatibility.(especially for c++ compiler)

// In CFAvailability.h // Enums and Options #if (__cplusplus && __cplusplus >= 201103L && (__has_extension(cxx_strong_enums) || __has_feature(objc_fixed_enum))) || (!__cplusplus && __has_feature(objc_fixed_enum))   #define CF_ENUM(_type, _name) enum _name : _type _name; enum _name : _type   #if (__cplusplus)     #define CF_OPTIONS(_type, _name) _type _name; enum : _type   #else     #define CF_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type   #endif #else   #define CF_ENUM(_type, _name) _type _name; enum   #define CF_OPTIONS(_type, _name) _type _name; enum #endif 

__cplusplus value in clang is 199711 and I can't test what this is exactly for, though.

</div
        
 
 

Список ответов

53
 
vote
vote
Лучший ответ
 
<Р> Там есть принципиальная разница между перечислением и битовой маской (опцией). Вы можете использовать перечисление в список эксклюзивных состояний. Битовая маска используется, когда некоторые свойства могут применяться одновременно. <Р> В обоих случаях вы используете целые числа, но вы посмотрите на них по-разному. С перечислением вы посмотрите на численном значении, с битмаской вы посмотрите на отдельных битах.
 <код> var doc = (new DOMParser()).parseFromString('<dummy/>', 'text/xml'); doc.removeChild(doc.documentElement); 5  
<Р> будет представлять только два состояния. Вы можете просто проверить это путем проверки равенства.
 <код> var doc = (new DOMParser()).parseFromString('<dummy/>', 'text/xml'); doc.removeChild(doc.documentElement); 6  
<Р> В то время как битовая будет представлять больше государств. Вы проверяете для отдельных битов с логическими или поразрядными операторами.
 <код> var doc = (new DOMParser()).parseFromString('<dummy/>', 'text/xml'); doc.removeChild(doc.documentElement); 7  
<Р> <сильный> ТЛ, д-р Перечисление дает имена чисел. Битовая маска дает имена битов.
 

There's a basic difference between an enum and a bitmask (option). You use an enum to list exclusive states. A bitmask is used when several properties can apply at the same time.

In both cases you use integers, but you look at them differently. With an enum you look at the numerical value, with bitmasks you look at the individual bits.

typedef NS_ENUM(NSInteger, MyStyle) {     MyStyleDefault,     MyStyleCustom }; 

Will only represent two states. You can simply check it by testing for equality.

switch (style){     case MyStyleDefault:         // int is 0     break;     case MyStyleCustom:         // int is 1     break; } 

While the bitmask will represent more states. You check for the individual bits with logic or bitwise operators.

typedef NS_OPTIONS(NSInteger, MyOption) {     MyOption1 = 1 << 0, // bits: 0001     MyOption2 = 1 << 1, // bits: 0010 };  if (option & MyOption1){ // last bit is 1     // bits are 0001 or 0011 } if (option & MyOption2){ // second to last bit is 1     // bits are 0010 or 0011 } if ((option & MyOption1) && (option & MyOption2)){ // last two bits are 1     // bits are 0011 } 

tl;dr An enum gives names to numbers. A bitmask gives names to bits.

</div
 
 
         
         
17
 
vote

Единственное серьезное различие состоит в том, что использование соответствующего макроса позволяет лучшему смыслу кода (завершение кода XCODE), чтобы сделать проверку типа и завершения кода. Например, NS_OPTIONS позволяет компилятору убедиться, что все enums вас <код> | вместе имеют один и тот же тип.

Для дальнейшего чтения см.: http://nyphter.com/ns_enum-ns_options/

.

Редактировать:

Теперь, когда наступает Swift, используя NS_ENUM / опции настоятельно рекомендуется таким образом, чтобы Enum можно было правильно соединено в SWIFT Enum.

 

The only major difference is that using the appropriate macro allows Code Sense (Xcode's code completion) to do type checking and code completion better. For example, NS_OPTIONS allows the compiler to make sure all the enums you | together are of the same type.

For further reading see: http://nshipster.com/ns_enum-ns_options/

Edit:

Now that Swift is coming, using NS_ENUM/OPTIONS is highly recommended so that the enum can be correctly bridged to a swift enum.

</div
 
 
     
     
7
 
vote

Единственное отличие состоит в том, чтобы сообщить разработчикам, используя значения, знали, имеет ли смысл использовать их в OR Ritmask.

Компилятор не заботится, какой из них вы используете :)

 

The only difference is to let developers using the values know if it makes sense to use them in an OR'ed bitmask.

The compiler doesn't care which one you use though :)

</div
 
 
1
 
vote

Я скопировал мой ответ от этого вопроса Объективное перечисление , NS_ENUM & AMP; Ns_options :

Поскольку пользователь, который добавляет этот вопрос, не был активным долгое время, возможно, вы можете предложить свои ответы для людей, которые ищут и находят здесь.

Ниже приведен ответ, скопированный :

Есть разница между ними, за исключением того, что они выводят различные перечисления.

При компиляции в режиме Objective-C ++ они генерируют другой код:

Это оригинальный код:

 <код> typedef NS_OPTIONS(NSUInteger, MyOptionType) {     MyOptionType1 = 1 << 0,     MyOptionType2 = 1 << 1, };  typedef NS_ENUM(NSUInteger, MyEnumType) {     MyEnumType1 = 1 << 0,     MyEnumType2 = 1 << 1, };   

Это код, когда макросы расширены в <Код> Objective-C компиляция:

 <код> 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, };   

Это код, когда макросы расширены в <Код> 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 :

Есть новая функция в C ++ 11, вы можете объявить тип для вас перечисления, до этого, перечисление типа, проводящее, определяется компилятором в соответствии с наибольшим значением перечислений.

Итак, в C ++ 11, поскольку вы можете решить размер вашего перечисления самостоятельно, вы можете переслать Enums Onums без фактического определения их, как это:

 <код> //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, }   

Эта функция удобна, и overyive-C импортирует эту функцию, но она приносит проблему при выполнении битовой расчета, как это:

 <код> enum MyEnumType aVar = MyEnumType1 | MyEnumType2;   

Этот код не может компилировать в компиляции C ++ / Objective-C ++, поскольку Avar считается типом <код> OR0 Но <код> OR1 имеет тип <код> OR2 Это назначение не может выполнить без литого типа, C ++ запрещает неявный тип отливки .

В это время нам нужны NS_OPTIONS, NS_OPTIONS отступают к Enum до C ++ 11, так что нет OR3 действительно, <код> OR4 - это просто другое имя для <код > OR5 , так что код как

 <код> OR6  

будет компилировать, так как он назначает <код> OR7 <код> OR8 .

 

I copied my answer from this question Objective-C Enumeration, NS_ENUM & NS_OPTIONS:

Since the user who add that question hasn't been active for a long time, maybe you can suggest my answers for people who search and find here.

BELOW IS THE ANSWER COPIED:

There is a difference between the two except that they infer different kind of enumerations.

When compiled in Objective-C++ mode, they generate different code:

this is the original code:

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

this is the code when macros are expanded in Objective-C compiling:

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, }; 

this is the code when macros are expanded in Objective-C++ compiling:

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, }; 

See the difference of NS_OPTIONS between two modes?

HERE IS THE REASON:

There is a new feature in C++ 11, you can declare a type for you enumeration, before that, the type holding enumeration is decided by compiler according to the largest value of enumerations.

So in C++ 11, since you can decide the size of your enumeration by yourself, you could forward declare enums without actually define them, like this:

//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, } 

This feature is handy, and Objective-C imports this feature , but it brings a problem, when doing bitwise calculation, like this:

enum MyEnumType aVar = MyEnumType1 | MyEnumType2; 

This code can't compile in C++/Objective-C++ compiling, since aVar is considered of type NSInteger but MyEnumType1 | MyEnumType2 is of type MyEnumType, this assignment can't perform without a type cast, C++ forbids implicit type casting.

At this time, we need NS_OPTIONS, NS_OPTIONS fall back to enum before C++ 11, so that there is no MyEnumType indeed, MyEnumType is just another name for NSInteger, so that code like

enum MyEnumType aVar = MyEnumType1 | MyEnumType2;  

will compile, since it is assigning NSInteger to NSInteger.

</div
 
 

Связанный проблема

1  Есть ли способ использовать координаты для выбора элемента в автоматизации тестирования IOS UI?  ( Is there a way to use coordinates to select an element in ios ui test automation ) 
Я имею дело с <код> UICollectionView , который имеет много элементов. Один из них, это <код> UISuplementaryView , который содержит множество кликабельных ячее...

6  Как изменить размер изображения, чтобы соответствовать ячейке UiableView?  ( How to resize image to fit uitableview cell ) 
Как соответствовать <код> UIImage в ячейку <код> UITableView , uableviewcell (?). Вы <Код> addSubview на <Код> cell или есть ли способ изменить размер <к...

3  Facebook IOS SDK: войдите в Facebook без всегда просить разрешений для приложения  ( Facebook ios sdk login to facebook without always ask for permissions for the a ) 
Я использую Facebook iOS SDK в моем приложении, и у меня есть два подобных вопроса: Есть ли способ узнать, есть ли в настоящее время войти пользователя? ...

1  UIREFRESHCONTROL в UiscrollView не срабатывает, когда используется большой заголовок  ( Uirefreshcontrol in a uiscrollview is not triggered when large title is used ) 
Когда я использую большие заголовки для панели навигации, добавленные элементы управления UIREFRESH для UIScrollView не срабатывают при вытянутом состоянии ...

4  Основные данные Nsfetchrequest также выбирают детей объектов объекта  ( Core data nsfetchrequest also fetches children objects of the entity ) 
Я новичок в iOS Dev и основные данные. У меня есть родительский NsmanageObject <код> @class Units; @interface Properties : NSManagedObject @property (nonat...

0  Уволить контроллер просмотра, когда он был назван «PerforgeGege»?  ( Dismiss view controller when it was called by performsegue ) 
У меня есть три контроллера просмотра: <код> Main , <код> VC1 , а <код> VC2 . Всякий раз, когда приложение запускает метод делегата определяет, какой VC будет...

2  IOS: Как нарисовать линию между двумя движущимися объектами?  ( Ios how to draw a line between two moving objects ) 
Я в основном имеющую массив объектов UIView, которые находятся на экране. Они перемещаются случайным образом вокруг, и я хотел бы иметь строку, соединяющую ка...

-1  Продолжайте получать ошибку безопасности транспорта HTTP, даже если я добавил код, чтобы обойти безопасность  ( Keep getting http transport security error even though i have added the code to ) 
Я пробовал множество различных методов, как правило, код, который я использую работы. Однако в этом случае я не уверен, если это делать с кодом из учебника, к...

1  Доступ к файлу, сохраненному на устройство WriteToFile  ( Accessing file saved to device writetofile ) 
Я экономя свой текст UItextView в файл, test.txt <код> NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSS...

7  Никогда не получайте загрузку данных в Google API для iOS  ( Never getting uploading data progress in google api for ios ) 
Я использую Googledrive API в своем приложении, чтобы загрузить файлы из моего приложения. До сих пор мне удалось найти хорошие результаты для загрузки всех т...

46  Как проверить push-уведомление работает в моем приложении  ( How to test push notification is working in my application ) 
В моем приложении я реализую службу Push-уведомления. У меня есть сервер поставщика контента, который содержит некоторые продукты в нем. Я создал сертификат...

0  Сохранить выбор UipickView к NsuserDefaults Swift  ( Save uipickerview selection to nsuserdefaults swift ) 
Я пытаюсь сохранить выбор пользователя от Uipickerview до NsuserDefaults. Я нашел ответы в Obj-C, но не быстрее. Вот мой код UipickView: <код> func numberOf...

0  ДолкоуторуtateTiointerfaceSorentation в IOS6  ( Shouldautorotatetointerfaceorientation in ios6 ) 
Я использую <код> UIImagePickerviewController , чтобы открыть библиотеку фото через присоединенный код ниже ... после вызова битовых строк кода. Приложение бы...

38  Android / iOS одноранговая архитектура [закрыто]  ( Android ios peer to peer architecture ) 
<в сторону CLASS = "S-NEWACTS S-WELTIVE__info JS-Post-New Imide MB16« Роль = «Статус»> закрыт . Этот вопрос должен быть больше Фокусированный . В настоя...

1  Обновление NsmanageObjects на заднем плане  ( Updating nsmanagedobjects in the background ) 
Я пытаюсь обновить NSManagedObject в фоновом режиме на основе свойств из сети сети. Возникли проблемы с обертыванием моей головы вокруг параллелизма. То, что ...

Связанный проблема

1  Есть ли способ использовать координаты для выбора элемента в автоматизации тестирования IOS UI? 
6  Как изменить размер изображения, чтобы соответствовать ячейке UiableView? 
3  Facebook IOS SDK: войдите в Facebook без всегда просить разрешений для приложения 
1  UIREFRESHCONTROL в UiscrollView не срабатывает, когда используется большой заголовок 
4  Основные данные Nsfetchrequest также выбирают детей объектов объекта 
0  Уволить контроллер просмотра, когда он был назван «PerforgeGege»? 
2  IOS: Как нарисовать линию между двумя движущимися объектами? 
-1  Продолжайте получать ошибку безопасности транспорта HTTP, даже если я добавил код, чтобы обойти безопасность 
1  Доступ к файлу, сохраненному на устройство WriteToFile 
7  Никогда не получайте загрузку данных в Google API для iOS 
46  Как проверить push-уведомление работает в моем приложении 
0  Сохранить выбор UipickView к NsuserDefaults Swift 
0  ДолкоуторуtateTiointerfaceSorentation в IOS6 
38  Android / iOS одноранговая архитектура [закрыто] 
1  Обновление NsmanageObjects на заднем плане