Estou desenvolvendo um aplicativo Cocoa e estou usando constantes NSString
s como formas de armazenar nomes-chave para minhas preferências.
Entendo que é uma boa ideia, pois permite a troca fácil de chaves, se necessário.
Além disso, é toda a noção de 'separar seus dados da sua lógica'.
Enfim, existe uma boa maneira de definir essas constantes uma vez para todo o aplicativo?
Tenho certeza de que existe uma maneira fácil e inteligente, mas agora minhas aulas redefinem as que eles usam.
Respostas:
Você deve criar um arquivo de cabeçalho como
(você pode usar, em
extern
vez de,FOUNDATION_EXPORT
se seu código não for usado em ambientes C / C ++ mistos ou em outras plataformas)Você pode incluir esse arquivo em cada arquivo que usa as constantes ou no cabeçalho pré-compilado do projeto.
Você define essas constantes em um arquivo .m como
Constants.m deve ser adicionado ao destino do aplicativo / estrutura para que ele seja vinculado ao produto final.
A vantagem de usar constantes de string em vez de
#define
constantes é que você pode testar a igualdade usando a comparação de ponteiro (stringInstance == MyFirstConstant
), que é muito mais rápida que a comparação de string ([stringInstance isEqualToString:MyFirstConstant]
) (e mais fácil de ler, IMO).fonte
NSString
propriedades emcopy
vez deretain
. Como tal, eles poderiam (e deveriam) manter uma instância diferente de suaNSString*
constante e a comparação direta de endereços de memória falharia. Além disso, eu presumiria que qualquer implementação razoavelmente ótima de-isEqualToString:
verificaria a igualdade de ponteiros antes de entrar na comparação detalhada de caracteres.Caminho mais fácil:
Melhor maneira:
Um benefício do segundo é que alterar o valor de uma constante não causa uma reconstrução de todo o programa.
fonte
extern NSString const * const MyConstant
, ou seja, torná-lo um ponteiro constante para um objeto constante em vez de apenas um ponteiro constante?Há também uma coisa a mencionar. Se você precisar de uma constante não global, use a
static
palavra-chaveExemplo
Por causa da
static
palavra - chave, essa const não é visível fora do arquivo.Correção menor por @QuinnTaylor : variáveis estáticas são visíveis em uma unidade de compilação . Geralmente, esse é um único arquivo .m (como neste exemplo), mas pode ser mordido se você o declarar em um cabeçalho incluído em outro lugar, pois você receberá erros de vinculador após a compilação
fonte
A resposta aceita (e correta) diz que "você pode incluir esse arquivo [Constants.h] ... no cabeçalho pré-compilado do projeto".
Como iniciante, tive dificuldade em fazer isso sem maiores explicações - veja como: No arquivo YourAppNameHere-Prefix.pch (este é o nome padrão do cabeçalho pré-compilado no Xcode), importe seu Constants.h dentro do
#ifdef __OBJC__
bloco .Observe também que os arquivos Constants.h e Constants.m não devem conter absolutamente mais nada, exceto o que está descrito na resposta aceita. (Sem interface ou implementação).
fonte
Geralmente estou usando o caminho postado por Barry Wark e Rahul Gupta.
Embora eu não goste de repetir as mesmas palavras nos arquivos .he .m. Observe que no exemplo a seguir a linha é quase idêntica nos dois arquivos:
Portanto, o que eu gosto de fazer é usar algumas máquinas do pré-processador C. Deixe-me explicar através do exemplo.
Eu tenho um arquivo de cabeçalho que define a macro
STR_CONST(name, value)
:No meu par .h / .m, onde desejo definir a constante, faço o seguinte:
et voila, eu tenho todas as informações sobre as constantes no arquivo .h.
fonte
Eu próprio tenho um cabeçalho dedicado a declarar constantes NSStrings usadas para preferências como:
Em seguida, declare-os no arquivo .m que acompanha:
Essa abordagem me serviu bem.
Editar: Observe que isso funciona melhor se as strings forem usadas em vários arquivos. Se apenas um arquivo o usar, você poderá fazê-lo
#define kNSStringConstant @"Constant NSString"
no arquivo .m que usa a string.fonte
Uma leve modificação na sugestão do @Krizz, para que funcione corretamente se o arquivo de cabeçalho das constantes for incluído na PCH, o que é bastante normal. Como o original é importado para a PCH, ele não será recarregado no
.m
arquivo e, portanto, você não recebe símbolos e o vinculador está descontente.No entanto, a seguinte modificação permite que ele funcione. É um pouco complicado, mas funciona.
Você vai precisar de 3 arquivos,
.h
arquivo que tem as definições constantes, o.h
arquivo e o.m
arquivo, eu vou usarConstantList.h
,Constants.h
eConstants.m
, respectivamente. o conteúdo deConstants.h
são simplesmente:e o
Constants.m
arquivo se parece com:Finalmente, o
ConstantList.h
arquivo possui as declarações reais e isso é tudo:Algumas coisas a serem observadas:
Eu tive que redefinir a macro no
.m
arquivo após#undef
inseri-la na macro a ser usada.Eu também tive que usar em
#include
vez disso#import
para que funcionasse corretamente e evitar que o compilador visse os valores pré-compilados anteriormente.Isso exigirá uma recompilação do seu PCH (e provavelmente todo o projeto) sempre que quaisquer valores forem alterados, o que não acontece se forem separados (e duplicados) normalmente.
Espero que seja útil para alguém.
fonte
extern
acima porFOUNDATION_EXPORT
.fonte
Como a Abizer disse, você pode colocá-lo no arquivo PCH. Outra maneira que não é tão suja é criar um arquivo de inclusão para todas as suas chaves e depois incluir no arquivo em que você está usando as chaves ou incluí-lo na PCH. Com eles em seu próprio arquivo de inclusão, isso fornece pelo menos um lugar para procurar e definir todas essas constantes.
fonte
Se você deseja algo como constantes globais; Uma maneira rápida e suja é colocar as constantes declarações no
pch
arquivo.fonte
Tente usar um método de classe:
Eu uso algumas vezes.
fonte
isEqualToString:
a comparação, o que é um custo adicional em tempo de execução. Quando você quiser constantes, faça constantes.Se você gosta de constante de espaço para nome, pode aproveitar struct, sexta-feira , P&R 19-08-2011: Constantes e funções com espaço para nome
fonte
__unsafe_unretained
qualificador para fazê-lo funcionar.Eu uso uma classe singleton, para que eu possa zombar da classe e alterar as constantes, se necessário para o teste. A classe constantes fica assim:
E é usado assim (observe o uso de uma abreviação para as constantes c - ele salva a digitação
[[Constants alloc] init]
toda vez):fonte
Se você deseja chamar algo assim a
NSString.newLine;
partir do objetivo c e deseja que seja constante estática, é possível criar algo assim rapidamente:E você tem uma definição constante legível e disponível em um tipo de sua escolha enquanto o estilo é limitado ao contexto do tipo.
fonte