A primeira pergunta é qual o escopo que você deseja que suas constantes tenham, que são realmente duas perguntas:
- Essas constantes são específicas para uma única classe ou faz sentido tê-las em todo o aplicativo?
- Se eles são específicos da classe, devem ser usados pelos clientes da classe ou apenas dentro da classe?
Se eles são específicos e internos a uma única classe, declare-os como static const
na parte superior do arquivo .m, da seguinte maneira:
static NSString *const MyThingNotificationKey = @"MyThingNotificationKey";
Se eles pertencem a uma única classe, mas devem ser públicos / usados por outras classes, declare-os como extern
no cabeçalho e defina-os no .m:
//.h
extern NSString *const MyThingNotificationKey;
//.m
NSString *const MyThingNotificationKey = @"MyThingNotificationKey";
Se eles devem ser globais, declare-os em um cabeçalho e defina-os em um módulo correspondente, especificamente para essas constantes.
Você pode misturá-las e combiná-las para diferentes constantes com diferentes níveis de quão global você deseja que sejam e para diferentes constantes globais que simplesmente não pertencem juntas - você pode colocá-las em módulos separados, cada um com seu próprio cabeçalho, se você quer.
Por que não #define
?
A resposta antiga é “macros não possuem informações de tipo”, mas hoje os compiladores são bastante inteligentes em fazer toda a verificação de tipos de literais (para os quais as macros se expandem) e também de variáveis.
A resposta moderna é porque o depurador não saberá sobre suas macros. Você não pode dizer [myThing addObserver:self forKey:MyThingNotificationKey]
em um comando debugger se MyThingNotificationKey
é uma macro; o depurador só pode saber se for uma variável.
Por que não enum
?
Bem, rmaddy me venceu nos comentários: enum
só pode definir constantes inteiras. Coisas como números de identificação serial, máscaras de bits, códigos de quatro bytes, etc.
Para esses fins, enum
é ótimo e você absolutamente deve usá-lo. (Melhor ainda, use as teclas NS_ENUM
eNS_OPTIONS
.) Para outras coisas, você deve usar outra coisa; enum
não faz nada além de números inteiros.
E outras perguntas
Eu estava pensando em importar o arquivo no arquivo Reddit-Prefix.pch para disponibilizar as constantes para todos os arquivos. É uma boa maneira de fazer as coisas?
Provavelmente inofensivo, mas provavelmente excessivo. Importe os cabeçalhos das constantes para onde precisar deles.
Quais são os casos de uso para cada uma dessas soluções?
#define
: Bastante limitado. Sinceramente, não tenho certeza de que exista uma boa razão para usar isso para constantes.
const
: Melhor para constantes locais. Além disso, você deve usar isso para o que você declarou em um cabeçalho e agora está definindo.
static const
: Melhor para constantes específicas de arquivo (ou classe).
extern const
: Você deve usar isso ao exportar uma constante em um cabeçalho.
Além disso, se estiver usando extern const
, preciso importar o arquivo ou as constantes estarão disponíveis globalmente sem importar o arquivo?
Você precisa importar o arquivo, em cada arquivo em que o usa ou no cabeçalho do prefixo.