Quelle est la meilleure façon de créer des constantes dans Objective-C

Je crée un client Reddit à des fins d’apprentissage. J’ai besoin d’un fichier contenant des constantes. Je pensais importer le fichier dans le fichier Reddit-Prefix.pch pour rendre les constantes disponibles pour tous les fichiers. Est-ce une bonne façon de faire les choses? J’ai aussi fait mes recherches et trouvé plusieurs méthodes pour créer des constantes, mais je ne sais pas lequel utiliser:

  • #define macro
  • const
  • static const
  • extern const
  • enum

Alors, quelle est la voie préférée? Quelle est la convention? Je sais que “ça dépend” mais ma question plus précisément est la suivante: quels sont les cas d’utilisation de chacune de ces solutions?

En outre, si vous utilisez extern const , dois-je importer le fichier ou les constantes seront disponibles globalement sans importer le fichier?

Une chose que je pourrais logiquement conclure est que enum est le meilleur choix pour définir quelque chose comme des domaines d’erreur personnalisés (est-ce que j’ai raison?). Mais qu’en est-il des autres?

La première question est de savoir quelle scope vous souhaitez avoir pour vos constantes, qui sont en réalité deux questions:

  • Ces constantes sont-elles spécifiques à une classe unique, ou est-il judicieux de les avoir toutes sur l’application?
  • S’ils sont spécifiques à une classe, sont-ils destinés à des clients de la classe ou uniquement au sein de la classe?

Si elles sont spécifiques et internes à une seule classe, déclarez-les comme static const en haut du fichier .m, comme ceci:

 static NSSsortingng *const MyThingNotificationKey = @"MyThingNotificationKey"; 

S’ils appartiennent à une seule classe mais doivent être publics / utilisés par d’autres classes, déclarez-les comme extern dans l’en-tête et définissez-les dans le fichier .m:

 //.h extern NSSsortingng *const MyThingNotificationKey; //.m NSSsortingng *const MyThingNotificationKey = @"MyThingNotificationKey"; 

Si elles doivent être globales, déclarez-les dans un en-tête et définissez-les dans un module correspondant, spécifiquement pour ces constantes.

Vous pouvez les mélanger et les associer pour différentes constantes avec différents niveaux de globalisation, et pour différentes constantes globales qui ne sont tout simplement pas associées – vous pouvez les placer dans des modules séparés, chacun avec son propre en-tête, si vous le souhaitez. vouloir.

Pourquoi pas #define ?

L’ancienne réponse est que «les macros n’ont pas d’informations sur les types», mais les compilateurs d’aujourd’hui sont assez intelligents pour effectuer toutes les vérifications de type des littéraux (ce que les macros développent) ainsi que les variables.

La réponse moderne est que le débogueur ne connaît pas vos macros. Vous ne pouvez pas dire [myThing addObserver:self forKey:MyThingNotificationKey] dans une commande de débogueur si MyThingNotificationKey est une macro; le débogueur ne peut le savoir que s’il s’agit d’une variable.

Pourquoi pas enum ?

Eh bien, rmaddy m’a battu dans les commentaires: enum ne peut définir que des constantes entières. Des éléments tels que les numéros d’identification série, les masques binarys, les codes à quatre octets, etc.

Pour ces fins, enum est génial et vous devez absolument l’utiliser. (Mieux encore, utilisez les macros NS_ENUM et NS_OPTIONS ). Pour d’autres choses, vous devez utiliser autre chose; enum ne fait que des entiers.

Et d’autres questions

Je pensais importer le fichier dans le fichier Reddit-Prefix.pch pour rendre les constantes disponibles pour tous les fichiers. Est-ce une bonne façon de faire les choses?

Probablement sans danger, mais probablement excessif. Importez vos en-têtes de constantes là où vous en avez besoin.

Quels sont les cas d’utilisation pour chacune de ces solutions?

  • #define : Assez limité. Honnêtement, je ne suis pas sûr qu’il y ait une bonne raison de l’utiliser pour les constantes.
  • const : meilleur pour les constantes locales. De plus, vous devez l’utiliser pour celui que vous avez déclaré dans un en-tête et que vous définissez maintenant.
  • static const : static const pour les constantes spécifiques à un fichier (ou à une classe).
  • extern const : Vous devez l’utiliser lors de l’exportation d’une constante dans un en-tête.

En outre, si vous utilisez extern const , dois-je importer le fichier ou les constantes seront disponibles globalement sans importer le fichier?

Vous devez importer le fichier, soit dans chaque fichier où vous l’utilisez, soit dans l’en-tête de préfixe.

FOUNDATION_EXPORT

Pensez à utiliser FOUNDATION_EXPORT pour un peu plus de compatibilité que extern car il est défini en base et comstack en formats compatibles pour C, C ++ et Win32.

Comme défini dans NSObjCRuntime.h

 #if defined(__cplusplus) #define FOUNDATION_EXTERN extern "C" #else #define FOUNDATION_EXTERN extern #endif #if TARGET_OS_WIN32 #if defined(NSBUILDINGFOUNDATION) #define FOUNDATION_EXPORT FOUNDATION_EXTERN __declspec(dllexport) #else #define FOUNDATION_EXPORT FOUNDATION_EXTERN __declspec(dllimport) #endif #define FOUNDATION_IMPORT FOUNDATION_EXTERN __declspec(dllimport) #else #define FOUNDATION_EXPORT FOUNDATION_EXTERN #define FOUNDATION_IMPORT FOUNDATION_EXTERN #endif