Як визначити та використовувати ENUM в Objective-C?


180

Я оголосив enum у моєму файлі реалізації, як показано нижче, і оголосив змінну цього типу в моєму інтерфейсі як PlayerState thePlayerState; і використовував змінну в своїх методах. Але я отримую помилки, вказуючи, що це незадекларовано. Як правильно оголосити та використовувати змінну типу PlayerState у своїх методах ?:

У файлі .m

@implementation View1Controller

    typedef enum playerStateTypes
        {
            PLAYER_OFF,
            PLAYER_PLAYING,
            PLAYER_PAUSED
        } PlayerState;

у файлі .h:

@interface View1Controller : UIViewController {

    PlayerState thePlayerState;

у якомусь методі у .m файлі:

-(void)doSomethin{

thePlayerState = PLAYER_OFF;

}

2
Тепер типом enum є thePlayerState. Що таке "PlayerStateTypes"?
user4951

3
Інформацію про NS_ENUM та його останній сучасний синтаксис дивіться у публікації NS_ENUM & NS_OPTIONS Метта Томпсона.
Василь Бурк

Відповіді:


109

Ваші typedefпотреби бути в заголовки (або який - або інший файл , який #importéd в ваш заголовок), оскільки в іншому випадку компілятор не знатиме , який розмір , щоб зробити PlayerStateІвар. Крім цього, мені це виглядає нормально.


Можливість розмістити його в окремому файлі здавалася правильною у моєму випадку. Я не знаю, чи це хороший підхід, але мені потрібно було використовувати один і той же перелік у двох різних ViewControllers (я та його делегат / джерело даних). Імпорт заголовка делегата / джерела даних призвів до помилки і, здається, занадто багато для простої потреби. Тому я створив новий .h файл із перерахуванням enum та імпортував його в обидва файли viewControllers.h. Працював як шарм.
Леандро Алвеш

7
Слід рекомендувати використовувати макрос NS_ENUM - оскільки це найкраща практика
khebbie

1
Ви повинні оголосити переліків, використовуючи NS_ENUMв Objective-C, якщо ви хочете, щоб ваш перелік був доступний у коді Swift.
smileyborg

@DaveDeLong, чи це все ще діє у 2015 році? Я typedefзадекларований у .mфайлі, і він збирається і працює добре.
Юліан Онофрей

@IulianOnofrei він увійде у файл .h, якщо вам потрібно використовувати enum в інших файлах. Якщо вам це потрібно лише в одному файлі, розміщення його у .m-файлі завжди було чудово.
Дейв ДеЛонг

206

Apple пропонує макрос, який допомагає забезпечити кращу сумісність коду, включаючи Swift. Використання макросу виглядає приблизно так.

typedef NS_ENUM(NSInteger, PlayerStateType) {
  PlayerStateOff,
  PlayerStatePlaying,
  PlayerStatePaused
};

Задокументовано тут


Чи можуть Obj C Enums мати такі змінні, як у Java? Якщо так, то як?
слюсар

Так що краще рішення другого?
Юліан Онофрей

3
Друге рішення краще (з використанням NS_ENUM), оскільки воно є більш сучасним, і тепер воно потрібно в Objective-C, якщо ви хочете, щоб ваш перелік був доступний у коді Swift.
усміхборг

Оновлений для показу другого рішення насправді краще.
rebelzach

У стандартній формі Apple ім'я типу повторюється для кожного значення перерахунку.
ThomasW

29

У .h:

typedef enum {
    PlayerStateOff,
    PlayerStatePlaying,
    PlayerStatePaused
} PlayerState;

1
Ви можете знайти подібну відповідь в інших питаннях ТА, але коли я переглядав переписки, це питання спливе спочатку, тому я додав відповідь і тут.
Бен Флінн

19

Для поточних проектів ви можете використовувати макроси NS_ENUM()або NS_OPTIONS()макроси.

typedef NS_ENUM(NSUInteger, PlayerState) {
        PLAYER_OFF,
        PLAYER_PLAYING,
        PLAYER_PAUSED
    };

2
... і що ще важливіше, ви повинні оголосити переліків, використовуючи NS_ENUMв Objective-C, якщо ви хочете, щоб ваш enum був доступний у коді Swift.
smileyborg

16

Ось як це робить Apple для таких класів, як NSString:

У файлі заголовка:

enum {
    PlayerStateOff,
    PlayerStatePlaying,
    PlayerStatePaused
};

typedef NSInteger PlayerState;

Зверніться до Правил кодування на веб-сайті http://developer.apple.com/


3
Це насправді не допомагає ОП. Хоча технічно правильно, це не говорить їм, як створити
переспіви

24
Посилання на developer.apple.com не є корисною. Чи є ще якесь місце, яке ви хотіли б навести замість цього?
Бретт

Скопіюйте / вставте документацію, яку вже надано, посилання на головну сторінку якої справді не допомагає іншим людям ...
Onder OZCAN

3
Зараз це застаріло, дивіться цю сторінку developer.apple.com/library/ios/releasenotes/ObjectiveC/…
Алекс Честер

8

Я рекомендую використовувати NS_OPTIONS або NS_ENUM. Більше про це можна прочитати тут: http://nshipster.com/ns_enum-ns_options/

Ось приклад з мого власного коду за допомогою NS_OPTIONS, у мене є утиліта, яка встановлює підшар (CALayer) на шарі UIView для створення межі.

Година файл:

typedef NS_OPTIONS(NSUInteger, BSTCMBorder) {
    BSTCMBOrderNoBorder     = 0,
    BSTCMBorderTop          = 1 << 0,
    BSTCMBorderRight        = 1 << 1,
    BSTCMBorderBottom       = 1 << 2,
    BSTCMBOrderLeft         = 1 << 3
};

@interface BSTCMBorderUtility : NSObject

+ (void)setBorderOnView:(UIView *)view
                 border:(BSTCMBorder)border
                  width:(CGFloat)width
                  color:(UIColor *)color;

@end

.M файл:

@implementation BSTCMBorderUtility

+ (void)setBorderOnView:(UIView *)view
                 border:(BSTCMBorder)border
                  width:(CGFloat)width
                  color:(UIColor *)color
{

    // Make a left border on the view
    if (border & BSTCMBOrderLeft) {

    }

    // Make a right border on the view
    if (border & BSTCMBorderRight) {

    }

    // Etc

}

@end
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.