objective-c - operator objective c




Constantes em Objective-C (9)

Estou desenvolvendo um aplicativo Cocoa e estou usando NSString constantes como formas de armazenar nomes-chave para minhas preferências.

Eu entendo isso é uma boa idéia, porque permite a fácil troca de chaves, se necessário. Além disso, é o todo 'separar seus dados de sua lógica' noção.

De qualquer forma, existe uma boa maneira de fazer essas constantes definidas uma vez para o aplicativo inteiro? Tenho certeza de que há uma maneira fácil e inteligente, mas agora minhas aulas apenas redefinem as que elas usam.


A resposta aceita (e correta) diz que "você pode incluir este arquivo [Constants.h] ... no cabeçalho pré-compilado do projeto."

Como novato, eu tive dificuldade em fazer isso sem mais explicações - aqui está como: No seu arquivo YourAppNameHere-Prefix.pch (este é o nome padrão para o cabeçalho pré-compilado no Xcode), importe seu Constants.h dentro do bloco #ifdef __OBJC__ .

#ifdef __OBJC__
  #import <UIKit/UIKit.h>
  #import <Foundation/Foundation.h>
  #import "Constants.h"
#endif

Observe também que os arquivos Constants.h e Constants.m devem conter absolutamente nada mais, exceto o que está descrito na resposta aceita. (Nenhuma interface ou implementação).


Caminho mais fácil:

// Prefs.h
#define PREFS_MY_CONSTANT @"prefs_my_constant"

Melhor maneira:

// Prefs.h
extern NSString * const PREFS_MY_CONSTANT;

// Prefs.m
NSString * const PREFS_MY_CONSTANT = @"prefs_my_constant";

Um benefício do segundo é que alterar o valor de uma constante não causa uma reconstrução de todo o programa.


Eu geralmente estou usando o caminho postado por Barry Wark e Rahul Gupta.

Embora, eu não goste de repetir as mesmas palavras nos arquivos .h e .m. Note que, no exemplo a seguir, a linha é quase idêntica em ambos os arquivos:

// file.h
extern NSString* const MyConst;

//file.m
NSString* const MyConst = @"Lorem ipsum";

Portanto, o que eu gosto de fazer é usar algum maquinário de pré-processamento de C. Deixe-me explicar através do exemplo.

Eu tenho um arquivo de cabeçalho que define a macro STR_CONST(name, value) :

// StringConsts.h
#ifdef SYNTHESIZE_CONSTS
# define STR_CONST(name, value) NSString* const name = @ value
#else
# define STR_CONST(name, value) extern NSString* const name
#endif

No meu par .h / .m onde eu quero definir a constante eu faço o seguinte:

// myfile.h
#import <StringConsts.h>

STR_CONST(MyConst, "Lorem Ipsum");
STR_CONST(MyOtherConst, "Hello world");

// myfile.m
#define SYNTHESIZE_CONSTS
#import "myfile.h"

et voila, Eu tenho todas as informações sobre as constantes no arquivo.


Eu mesmo tenho um cabeçalho dedicado a declarar NSStrings constantes usadas para preferências como:

extern NSString * const PPRememberMusicList;
extern NSString * const PPLoadMusicAtListLoad;
extern NSString * const PPAfterPlayingMusic;
extern NSString * const PPGotoStartupAfterPlaying;

Em seguida, declarando-os no arquivo .m que o acompanha:

NSString * const PPRememberMusicList = @"Remember Music List";
NSString * const PPLoadMusicAtListLoad = @"Load music when loading list";
NSString * const PPAfterPlayingMusic = @"After playing music";
NSString * const PPGotoStartupAfterPlaying = @"Go to startup pos. after playing";

Essa abordagem me serviu bem.

Edit: Note que isso funciona melhor se as seqüências de caracteres são usadas em vários arquivos. Se apenas um arquivo usa, você pode fazer #define kNSStringConstant @"Constant NSString" no arquivo .m que usa a string.


Há também uma coisa a mencionar. Se você precisar de uma constante não global, deverá usar a palavra-chave static .

Exemplo

// In your *.m file
static NSString * const kNSStringConst = @"const value";

Por causa da palavra-chave static , essa const não é visível fora do arquivo.

Correção menor por @QuinnTaylor : variáveis ​​estáticas são visíveis dentro de uma unidade de compilação . Normalmente, este é um único arquivo .m (como neste exemplo), mas pode ser mordido se você o declarar em um cabeçalho que esteja incluído em outro lugar, já que você receberá erros de vinculação após a compilação


Se você gosta de namespace constante, você pode aproveitar struct, Friday Q & A 2011-08-19: Constantes e Funções com Namespaces

// in the header
extern const struct MANotifyingArrayNotificationsStruct
{
    NSString *didAddObject;
    NSString *didChangeObject;
    NSString *didRemoveObject;
} MANotifyingArrayNotifications;

// in the implementation
const struct MANotifyingArrayNotificationsStruct MANotifyingArrayNotifications = {
    .didAddObject = @"didAddObject",
    .didChangeObject = @"didChangeObject",
    .didRemoveObject = @"didRemoveObject"
};

Tente usar um método de classe:

+(NSString*)theMainTitle
{
    return @"Hello World";
}

Eu uso isso às vezes.


Uma ligeira modificação da 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 o PCH, ele não é recarregado no arquivo .m e, portanto, você não recebe símbolos e o vinculador não está satisfeito.

No entanto, a seguinte modificação permite que ele funcione. É um pouco confuso, mas funciona.

Você precisará de 3 arquivos, o arquivo .h que tenha as definições de constantes, o arquivo .h e o arquivo .m , eu usarei ConstantList.h , Constants.h Constants.m , respectivamente. o conteúdo de Constants.h é simplesmente:

// Constants.h
#define STR_CONST(name, value) extern NSString* const name
#include "ConstantList.h"

e o arquivo Constants.m parece com:

// Constants.m
#ifdef STR_CONST
    #undef STR_CONST
#endif
#define STR_CONST(name, value) NSString* const name = @ value
#include "ConstantList.h"

Finalmente, o arquivo ConstantList.h tem as declarações reais e isso é tudo:

// ConstantList.h
STR_CONST(kMyConstant, "Value");

Algumas coisas a serem observadas:

  1. Eu tive que redefinir a macro no arquivo .m depois de #undef ele para a macro a ser usada.

  2. Eu também tive que usar #include vez de #import para que isso funcione corretamente e evite que o compilador veja os valores previamente pré-compilados.

  3. Isso exigirá uma recompilação de seu PCH (e provavelmente o projeto inteiro) sempre que algum valor for alterado, o que não é o caso se eles forem separados (e duplicados) normalmente.

Espero que seja útil para alguém.


// Prefs.h
extern NSString * const RAHUL;

// Prefs.m
NSString * const RAHUL = @"rahul";




constants