Como definir e usar um ENUM no Objective-C?

180

Declarei uma enumeração no meu arquivo de implementação, como mostrado abaixo, e declarei uma variável desse tipo na minha interface como PlayerState thePlayerState; e usei a variável em meus métodos. Mas estou recebendo erros afirmando que não está declarado. Como declaro e uso corretamente uma variável do tipo PlayerState nos meus métodos?

No arquivo .m

@implementation View1Controller

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

no arquivo .h:

@interface View1Controller : UIViewController {

    PlayerState thePlayerState;

em algum método no arquivo .m:

-(void)doSomethin{

thePlayerState = PLAYER_OFF;

}
RexOnRoids
fonte
2
Agora, o tipo de enumeração é thePlayerState. O que o playerStateTypes se torna?
user4951
3
Para obter informações sobre o NS_ENUM e sua sintaxe moderna mais recente, consulte a postagem NS_ENUM & NS_OPTIONS de Mattt Thompson.
Basil Bourque

Respostas:

109

Você typedefprecisa estar no arquivo de cabeçalho (ou em algum outro arquivo #importinserido no cabeçalho), porque, caso contrário, o compilador não saberá qual o tamanho para criar o PlayerStateivar. Fora isso, parece bom para mim.

Dave DeLong
fonte
A opção de colocá-lo em um arquivo separado parecia correta no meu caso. Não sei se essa é uma boa abordagem, mas eu precisava usar a mesma enumeração em dois ViewControllers diferentes (self e seu delegate / datasource). A importação do cabeçalho do representante / fonte de dados resultou em um erro e parece demais para uma simples necessidade. Então, criei um novo arquivo .h com a enum declarada e o importei no arquivo viewControllers.h. Funcionou como um encanto.
Leandro Alves
7
Deve recomendar a usar a macro NS_ENUM - uma vez que esta é a melhor prática
khebbie
1
Você deve declarar enumerações usando NS_ENUMno Objective-C se quiser que sua enumeração esteja disponível no código Swift.
smileyborg
@DaveDeLong, isso ainda é válido em 2015? Eu tenho o typedefdeclarado no .marquivo e ele compila e roda bem.
Iulian Onofrei
@IulianOnofrei, ele entraria no arquivo .h se você precisar usar o enum em outros arquivos. Se você precisar apenas de um arquivo, colocá-lo no arquivo .m sempre foi perfeitamente adequado.
Dave DeLong
206

A Apple fornece uma macro para ajudar a fornecer melhor compatibilidade de código, incluindo Swift. Usar a macro fica assim.

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

Documentado aqui

rebelzach
fonte
As Enums de Obj C podem ter variáveis ​​de membro como em Java? Se sim, como?
clocksmith
Então a segunda solução é melhor?
Iulian Onofrei
3
A segunda solução é melhor (usando NS_ENUM), pois é mais moderna e agora é necessária no Objective-C se você deseja que sua enumeração esteja disponível no código Swift.
smileyborg
Atualizado para mostrar que a segunda solução é de fato melhor.
rebelzach
No formulário padrão da Apple, o nome do tipo é repetido para cada valor de enumeração.
9189 Thomas
29

No .h:

typedef enum {
    PlayerStateOff,
    PlayerStatePlaying,
    PlayerStatePaused
} PlayerState;
Ben Flynn
fonte
1
Você pode encontrar uma resposta como essa em outras perguntas do SO, mas quando eu estava analisando enums, essa pergunta apareceu primeiro, então eu adicionei a resposta aqui também.
Ben Flynn
19

Nos projetos atuais, convém usar as NS_ENUM()ou NS_OPTIONS()macros.

typedef NS_ENUM(NSUInteger, PlayerState) {
        PLAYER_OFF,
        PLAYER_PLAYING,
        PLAYER_PAUSED
    };
sean woodward
fonte
2
... e mais importante agora, você deve declarar enumerações usando NS_ENUMno Objective-C se quiser que sua enumeração esteja disponível no código Swift.
smileyborg
16

É assim que a Apple faz isso para classes como o NSString:

No arquivo de cabeçalho:

enum {
    PlayerStateOff,
    PlayerStatePlaying,
    PlayerStatePaused
};

typedef NSInteger PlayerState;

Consulte Diretrizes de codificação em http://developer.apple.com/

Santhos
fonte
3
Isso realmente não ajuda o OP. Embora tecnicamente correto, não dizer-lhes como criar um enum reutilizável
RyanR
24
Vincular a developer.apple.com não é realmente útil. Existe algum outro lugar que você gostaria de citar?
Brett
Copiar / colar documentação que já deu, o link que é a página realmente não está ajudando a outro povo ...
Onder OZCAN
3
Agora está desatualizado, consulte esta página developer.apple.com/library/ios/releasenotes/ObjectiveC/…
Alex Chesters
8

Eu recomendo usar NS_OPTIONS ou NS_ENUM. Você pode ler mais sobre isso aqui: http://nshipster.com/ns_enum-ns_options/

Aqui está um exemplo do meu próprio código usando NS_OPTIONS, eu tenho um utilitário que define uma subcamada (CALayer) na camada de um UIView para criar uma borda.

O h. Arquivo:

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

O arquivo .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
Johannes
fonte