Je suis en train de développer une application Cocoa et j'utilise des NSString
s constants comme moyen de stocker des noms de clés pour mes préférences.
Je comprends que c'est une bonne idée car elle permet de changer facilement les clés si nécessaire.
De plus, c'est toute la notion de «séparer vos données de votre logique».
Quoi qu'il en soit, existe-t-il un bon moyen de définir ces constantes une fois pour l'ensemble de l'application?
Je suis sûr qu'il existe un moyen simple et intelligent, mais pour l'instant mes cours redéfinissent ceux qu'ils utilisent.
Réponses:
Vous devez créer un fichier d'en-tête comme
(vous pouvez utiliser à la
extern
place deFOUNDATION_EXPORT
si votre code ne sera pas utilisé dans des environnements mixtes C / C ++ ou sur d'autres plates-formes)Vous pouvez inclure ce fichier dans chaque fichier qui utilise les constantes ou dans l'en-tête précompilé du projet.
Vous définissez ces constantes dans un fichier .m comme
Constants.m doit être ajouté à la cible de votre application / framework afin qu'il soit lié au produit final.
L'avantage d'utiliser des constantes de chaîne au lieu de constantes
#define
'd est que vous pouvez tester l'égalité en utilisant la comparaison de pointeurs (stringInstance == MyFirstConstant
) qui est beaucoup plus rapide que la comparaison de chaînes ([stringInstance isEqualToString:MyFirstConstant]
) (et plus facile à lire, IMO).la source
NSString
propriétés aveccopy
au lieu deretain
. En tant que tels, ils pourraient (et devraient) contenir une instance différente de votreNSString*
constante, et la comparaison directe des adresses mémoire échouerait. En outre, je suppose que toute implémentation raisonnablement optimale de-isEqualToString:
vérifierait l'égalité du pointeur avant d'entrer dans le vif du sujet de la comparaison des caractères.Manière la plus simple:
Meilleure façon:
L'un des avantages de la seconde est que la modification de la valeur d'une constante n'entraîne pas une reconstruction de l'ensemble de votre programme.
la source
extern NSString const * const MyConstant
, c'est-à-dire en faire un pointeur constant vers un objet constant plutôt qu'un simple pointeur constant?Il y a aussi une chose à mentionner. Si vous avez besoin d'une constante non globale, vous devez utiliser un
static
mot-clé.Exemple
En raison du
static
mot clé, cette constante n'est pas visible en dehors du fichier.Correction mineure par @QuinnTaylor : les variables statiques sont visibles dans une unité de compilation . Habituellement, il s'agit d'un seul fichier .m (comme dans cet exemple), mais il peut vous mordre si vous le déclarez dans un en-tête qui est inclus ailleurs, car vous obtiendrez des erreurs de l'éditeur de liens après la compilation
la source
La réponse acceptée (et correcte) indique que "vous pouvez inclure ce fichier [Constants.h] ... dans l'en-tête précompilé du projet".
En tant que novice, j'ai eu du mal à le faire sans autre explication - voici comment: dans votre fichier YourAppNameHere-Prefix.pch (c'est le nom par défaut pour l'en-tête précompilé dans Xcode), importez votre Constants.h à l'intérieur du
#ifdef __OBJC__
bloc .Notez également que les fichiers Constants.h et Constants.m ne doivent contenir absolument rien d'autre, sauf ce qui est décrit dans la réponse acceptée. (Aucune interface ou implémentation).
la source
J'utilise généralement la manière affichée par Barry Wark et Rahul Gupta.
Cependant, je n'aime pas répéter les mêmes mots dans les fichiers .h et .m. Notez que dans l'exemple suivant, la ligne est presque identique dans les deux fichiers:
Par conséquent, ce que j'aime faire est d'utiliser des machines de préprocesseur C. Permettez-moi de vous expliquer à travers l'exemple.
J'ai un fichier d'en-tête qui définit la macro
STR_CONST(name, value)
:Dans ma paire .h / .m où je veux définir la constante, je fais ce qui suit:
et voila, j'ai toutes les informations sur les constantes dans le fichier .h uniquement.
la source
J'ai moi-même un en-tête dédié à la déclaration des NSStrings constants utilisés pour les préférences comme ceci:
Puis en les déclarant dans le fichier .m joint:
Cette approche m'a bien servi.
Modifier: notez que cela fonctionne mieux si les chaînes sont utilisées dans plusieurs fichiers. Si un seul fichier l'utilise, vous pouvez simplement le faire
#define kNSStringConstant @"Constant NSString"
dans le fichier .m qui utilise la chaîne.la source
Une légère modification de la suggestion de @Krizz, pour qu'elle fonctionne correctement si le fichier d'en-tête des constantes doit être inclus dans le PCH, ce qui est plutôt normal. Étant donné que l'original est importé dans le PCH, il ne le rechargera pas dans le
.m
fichier et donc vous n'obtiendrez aucun symbole et l'éditeur de liens est mécontent.Cependant, la modification suivante lui permet de fonctionner. C'est un peu compliqué, mais ça marche.
Vous aurez besoin de 3 fichiers,
.h
fichier qui a les définitions constantes, le.h
fichier et le.m
fichier, je vais utiliserConstantList.h
,Constants.h
etConstants.m
, respectivement. le contenu deConstants.h
est simplement:et le
Constants.m
fichier ressemble à:Enfin, le
ConstantList.h
fichier contient les déclarations réelles et c'est tout:Quelques points à noter:
J'ai dû redéfinir la macro dans le
.m
fichier après l'avoir#undef
ing pour que la macro soit utilisée.J'ai également dû utiliser
#include
au lieu de#import
pour que cela fonctionne correctement et éviter que le compilateur ne voie les valeurs précédemment précompilées.Cela nécessitera une recompilation de votre PCH (et probablement de l'ensemble du projet) chaque fois que des valeurs sont modifiées, ce qui n'est pas le cas si elles sont séparées (et dupliquées) comme d'habitude.
J'espère que cela est utile pour quelqu'un.
la source
extern
précède par leFOUNDATION_EXPORT
.la source
Comme l'a dit Abizer, vous pouvez le mettre dans le fichier PCH. Une autre façon qui n'est pas si sale est de créer un fichier d'inclusion pour toutes vos clés, puis de l'inclure dans le fichier dans lequel vous utilisez les clés ou de l'inclure dans le PCH. Avec eux dans leur propre fichier include, cela vous donne au moins un endroit pour rechercher et définir toutes ces constantes.
la source
Si vous voulez quelque chose comme des constantes globales; un moyen rapide et sale est de mettre les déclarations constantes dans le
pch
fichier.la source
Essayez d'utiliser une méthode de classe:
Je l'utilise parfois.
la source
isEqualToString:
pour la comparaison, qui est un coût supplémentaire au moment de l'exécution. Lorsque vous voulez des constantes, créez des constantes.Si vous aimez la constante d'espace de noms, vous pouvez tirer parti de struct, Friday Q&A 2011-08-19: Constantes et fonctions d'espaces de noms
la source
__unsafe_unretained
qualificateur pour le faire fonctionner.J'utilise une classe singleton, afin de pouvoir me moquer de la classe et modifier les constantes si nécessaire pour les tests. La classe des constantes ressemble à ceci:
Et il est utilisé comme ceci (notez l'utilisation d'un raccourci pour les constantes c - il enregistre la frappe à
[[Constants alloc] init]
chaque fois):la source
Si vous voulez appeler quelque chose comme ça à
NSString.newLine;
partir de l'objectif c et que vous voulez que ce soit une constante statique, vous pouvez créer quelque chose comme ça dans swift:Et vous avez une belle définition constante lisible, et disponible à partir d'un type de votre choix tout en étant limité au contexte du type.
la source