Je suis un peu confus quand il est préférable d’utiliser:
static NSSsortingng *AppQuitGracefullyKey = @"AppQuitGracefully";
au lieu de
#define AppQuitGracefullyKey @"AppQuitGracefully"
J’ai vu des questions comme celles-ci pour C ou C ++, et je pense que ce qui est différent ici, c’est spécifiquement pour Objective C, en utilisant un object et sur un périphérique comme l’iPhone. Je ne saisis pas encore
Une utilisation serait:
appQuitGracefully = [[NSUserDefaults standardUserDefaults] integerForKey: AppQuitGracefullyKey];
Ou c’est juste une question de style?
Merci.
Si vous utilisez un fichier statique, le compilateur incorporera exactement une copie de la chaîne dans votre fichier binary et transmettra simplement des pointeurs à cette chaîne, ce qui générera des fichiers binarys plus compacts. Si vous utilisez un #define, une copie distincte de la chaîne sera stockée dans la source à chaque utilisation. La coalescence constante des chaînes gérera un grand nombre de dups, mais vous faites en sorte que le lieur fonctionne plus fort sans aucune raison.
Voir “statique const” vs “#define” vs “enum” . Le principal avantage de la static
est la sécurité de type.
En dehors de cela, l’approche #define
introduit une flexibilité de la concaténation de chaînes en ligne qui ne peut pas être réalisée avec des variables statiques, par exemple
#define ROOT_PATH @"/System/Library/Frameworks" [[NSBundle bundleWithPath:ROOT_PATH@"/UIKit.framework"] load];
mais ce n’est probablement pas un bon style :).
Après quelques recherches ( cette question / réponse entre autres), je pense qu’il est important de dire que chaque fois que vous utilisez un littéral de chaîne @"AppQuitGracefully"
une chaîne constante est créée, et peu importe le nombre de fois que vous l’utilisez, le même object
Donc je pense (et je m’excuse si je me trompe) que cette phrase dans la réponse ci-dessus est fausse: If you use a #define, there will be a separate copy of the ssortingng stored in the source on each use.
Je ne recommanderais en fait ni l’un ni l’autre, vous devriez plutôt utiliser extern
. Objective-c définit déjà FOUNDATION_EXPORT
qui est plus portable que extern
, donc une instance NSSsortingng
globale ressemblerait à ceci:
.h
FOUNDATION_EXPORT NSSsortingng * const AppQuitGracefullyKey;
.m
NSSsortingng * const AppQuitGracefullyKey = @"AppQuitGracefully";
Je mets généralement ces fichiers de déclaration (tels que MyProjectDecl.h
) et les importe quand j’en ai besoin.
Il existe quelques différences avec ces approches:
#define ((int)1)
) mais à quoi ça sert? De plus, cette approche présente des inconvénients pour le débogage. Les compilateurs préfèrent les constantes. Voir cette discussion. Statique et externe diffèrent en visibilité. Il convient également de noter qu’aucune de ces approches ne duplique la chaîne (même pas #define
) car le compilateur utilise Ssortingng Interning pour empêcher cela. Dans ce post de NSHipster, ils montrent des preuves:
NSSsortingng *a = @"Hello"; NSSsortingng *b = @"Hello"; BOOL wtf = (a == b); // YES
L’opérateur ==
renvoie YES
uniquement si les deux variables pointent vers la même instance. Et comme vous pouvez le voir, c’est le cas.
La conclusion est la suivante: utilisez FOUNDATION_EXPORT
pour les constantes globales. Il est compatible avec le débogage et sera visible partout dans votre projet.
J’utilise static
quand j’ai besoin d’exporter des symboles NSSsortingng d’une bibliothèque ou d’un framework. J’utilise #define
quand j’ai besoin d’une chaîne dans de nombreux endroits que je peux changer facilement. De toute façon, le compilateur et l’éditeur de liens s’occuperont des optimisations.
UTILISATION #define:
vous ne pouvez pas déboguer la valeur de l’identifiant
travailler avec #define et les autres macros sont un travail de pré-processeur, quand vous appuyez sur Build / Run en premier il va prétraiter le code source, il va fonctionner avec toutes les macros (en commençant par le symbole #),
Supposons que vous ayez créé,
#define LanguageTypeEnglish @"en"
et utilisé à 2 endroits dans votre code.
NSSsortingng *language = LanguageTypeEnglish; NSSsortingng *languageCode = LanguageTypeEnglish;
il remplacera “LanguageTypeEnglish” par @"en"
, à tous les endroits. Donc, 2 copies de @"en"
seront générées. c’est à dire
NSSsortingng *language = @"en"; NSSsortingng *languageCode = @"en";
Rappelez-vous, jusqu’à ce que ce processus, le compilateur n’est pas dans l’image.
Après le prétraitement de toutes les macros, le complier apparaît, et il obtiendra un code de saisie comme celui-ci,
NSSsortingng *language = @"en"; NSSsortingng *languageCode = @"en";
et comstackr
UTILISATION statique:
il respecte la scope et est de type sécurisé. vous pouvez déboguer la valeur de l’identifiant
Pendant le processus de compilation si le compilateur a été trouvé,
static NSSsortingng *LanguageTypeRussian = @"ru";
alors il vérifiera si la variable avec le même nom est stockée précédemment, si oui, elle ne fera que passer le pointeur de cette variable, sinon elle créera cette variable et passera son pointeur, la prochaine fois elle ne fera que passer le pointeur de le même.
Donc, en utilisant statique, une seule copie de la variable est générée dans la scope.