Как использовать перечисляемые типы данных в Objective-C?

Я работаю над несколькими проектами iOS, где, по-моему, перечислены типы данных, которые будут полезны для меня. Например, у меня есть игра, в которой игрок может ходить в нескольких направлениях. Я мог бы просто определить четыре константы со строковыми значениями как kDirectionUp, kDirectionDown и т.д.

Я думаю, что перечисляемый тип будет лучше здесь. Это верно? Если да, то каким образом я могу определить перечисление здесь, чтобы впоследствии сравнить значения? (Как в, if(someValue == kDirectionUp){})

Ответ 1

Это звучит как правильная вещь.

Очень просто создавать перечисления в Objective-C с использованием определений типов C-стиля. Например, в одном из моих файлов заголовков у меня есть следующее определение типа:

typedef enum {
  CFPosterViewTypePoster = 0,
  CFPosterViewTypeStart, // 1
  CFPosterViewTypeEnd,   // 2
  ....                   // 3
} CFPosterViewType;   

Вы определяете объект CFPosterViewType и устанавливаете его в одно из значений:

CFPosterViewType posterType = CFPosterViewTypeStart;

При сравнении значений CFPosterViewType это так же просто, как делать следующее:

if (posterType == CFPosterViewTypePoster) {
    // do something
}

Обратите внимание, что пронумерованные номера в перечислении выше являются неявными значениями. Если вы хотите сделать что-то по-другому, скажем, определите битовую маску или что-нибудь еще, где вам нужны значения, отличные от значения по умолчанию, вам необходимо явно определить их.

Ответ 2

В файле заголовка определите тип enum, например:

// SomeHeaderFile.h
typedef enum {
    MOPlayerDirectionNone,
    MOPlayerDirectionUp,
    MOPlayerDirectionDown,
    …
} MOPlayerDirection;

Всякий раз, когда вам нужно использовать MOPlayerDirection, #import этот файл заголовка. Затем вы можете использовать его как тип, так и возможные значения.

Например:

#import "SomeHeaderFile.h"

@interface MOPlayer : NSObject {
    MOPlayerDirection currentDirection;
}

- (void)moveToDirection:(MOPlayerDirection)direction;
- (void)halt;
@end

и

#import "SomeHeaderFile.h"
#import "MOPlayer.h"

@implementation MOPlayer

- (id)init {
    self = [super init];
    if (self) {
        currentDirection = MOPlayerDirectionNone;
    }
    return self;
}

- (void)moveToDirection:(MOPlayerDirection)direction {
    currentDirection = direction;

    switch (currentDirection) {
        case MOPlayerDirectionUp:
            // do something
            break;

        case MOPlayerDirectionDown:
            // do something
            break;
    }
}

- (void)halt {
    if (currentDirection != MOPlayerDirectionNone) {
        // do something
        currentDirection = MOPlayerDirectionNone;
    }
}

@end

Если перечисление тесно связано с классом, его общий способ определить его в том же заголовочном файле, что и объявление класса. В приведенном выше примере вместо определения MOPlayerDirection в SomeHeaderFile.h вы можете определить его в MOPlayer.h вместо этого.

Ответ 3

Просто определите их в верхней части файла:

enum    // direction types
{
    kDirectionUp = 0,
    kDirectionDown, // 1
    kDirectionLeft, // 2
    kDirectionRight // 3

};

тогда вы можете позвонить по мере необходимости:

if(someValue == kDirectionUp){ // do something }