#objective-c #enums
#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)ha<
@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.
Комментарии:
1. Я думаю,
MOPlayerDirection *currentDirection
вероятно, должно бытьMOPlayerDirection currentDirection
;-). Вероятно, это не имело бы значения здесь, но более новый способ выполнитьtypedef
часть, похоже, состоит в том, чтобы поместить явноеtypedef NSUInteger MOPlayerDirection;
после перечисления, чтобы помочь компилятору.2. @NSGod Спасибо; автопилот FTL. 🙂
3. @NSGod Я не совсем понимаю, как
NSUInteger
это помогло бы компилятору. Компилятор волен выбирать базовый тип данных дляenum
, и тип данных гарантированно будет одним из целочисленных типов данных.4. @NSGod Хотя это было бы верно для перечислений в битовой маске.
Ответ №3:
Просто определите их в верхней части вашего файла:
enum // direction types
{
kDirectionUp = 0,
kDirectionDown, // 1
kDirectionLeft, // 2
kDirectionRight // 3
};
затем вы можете вызывать по мере необходимости:
if(someValue == kDirectionUp){ // do something }