it-swarm.com.de

Was ist der beste Weg, um Konstanten in Objective-C zu erstellen?

Ich erstelle einen Reddit-Client zu Lernzwecken. Ich brauche eine Datei mit Konstanten. Ich habe darüber nachgedacht, die Datei in die Datei Reddit-Prefix.pch Zu importieren, um die Konstanten für alle Dateien verfügbar zu machen. Ist es eine gute Möglichkeit, Dinge zu tun? Außerdem habe ich meine Recherche durchgeführt und verschiedene Methoden zum Erstellen von Konstanten gefunden, aber ich weiß nicht, welche ich verwenden soll:

  • Makro #define
  • const
  • static const
  • extern const
  • enum

Welcher Weg ist der bevorzugte Weg? Was ist die Konvention? Ich weiß, dass "es abhängt", aber meine Frage ist genauer: Was sind die Anwendungsfälle für jede dieser Lösungen?

Wenn ich extern const Verwende, muss ich die Datei importieren, oder die Konstanten sind global verfügbar, ohne die Datei zu importieren?

Eine logische Schlussfolgerung ist, dass enum die beste Wahl ist, wenn Sie so etwas wie benutzerdefinierte Fehlerdomänen definieren (habe ich tatsächlich Recht?). Aber was ist mit den anderen?

154
Robert Audi

Die erste Frage ist, welchen Bereich Ihre Konstanten haben sollen. Das sind zwei Fragen:

  • Sind diese Konstanten spezifisch für eine einzelne Klasse, oder ist es sinnvoll, sie in der gesamten Anwendung zu verwenden?
  • Wenn sie klassenspezifisch sind, dürfen sie von Clients der Klasse oder nur innerhalb der Klasse verwendet werden?

Wenn sie spezifisch und für eine einzelne Klasse intern sind, deklarieren Sie sie als static const am oberen Rand der .m-Datei, wie folgt:

static NSString *const MyThingNotificationKey = @"MyThingNotificationKey";

Wenn sie sich auf eine einzelne Klasse beziehen, aber von anderen Klassen öffentlich/verwendet werden sollen, deklarieren Sie sie im Header als extern und definieren Sie sie in der .m:

//.h
extern NSString *const MyThingNotificationKey;

//.m
NSString *const MyThingNotificationKey = @"MyThingNotificationKey";

Wenn sie global sein sollen, deklarieren Sie sie in einem Header und definieren Sie sie in einem entsprechenden Modul, speziell für diese Konstanten.

Sie können diese für verschiedene Konstanten mit unterschiedlichen Ebenen der Globalität, die Sie möchten, und für verschiedene globale Konstanten, die einfach nicht zusammengehören, mischen und zuordnen wollen.

Warum nicht #define?

Die alte Antwort lautet: "Makros haben keine Typinformationen", aber Compiler sind heutzutage ziemlich schlau darin, alle Typprüfungen für Literale (in die Makros erweitert werden) und Variablen durchzuführen.

Die moderne Antwort ist, dass der Debugger nichts von Ihren Makros weiß. Sie können nicht sagen, [myThing addObserver:self forKey:MyThingNotificationKey] in einem Debugger-Befehl, wenn MyThingNotificationKey ein Makro ist; Der Debugger kann nur wissen, ob es sich um eine Variable handelt.

Warum nicht enum?

Nun, rmaddy hat mich in den Kommentaren geschlagen: enum kann nur ganzzahlige Konstanten definieren. Dinge wie Seriennummern, Bitmasken, Vier-Byte-Codes usw.

Für diese Zwecke ist enum großartig und Sie sollten es unbedingt verwenden. (Noch besser, benutze das NS_ENUM und NS_OPTIONS Makros .) Für andere Dinge müssen Sie etwas anderes verwenden ; enum macht nur Ganzzahlen.

Und andere Fragen

Ich dachte darüber nach, die Datei in die Datei Reddit-Prefix.pch zu importieren, um die Konstanten für alle Dateien verfügbar zu machen. Ist es eine gute Art, Dinge zu tun?

Wahrscheinlich harmlos, aber wahrscheinlich übertrieben. Importieren Sie Ihre Konstanten-Header dort, wo Sie sie benötigen.

Was sind die Anwendungsfälle für jede dieser Lösungen?

  • #define: Ziemlich begrenzt. Ich bin mir ehrlich gesagt nicht sicher, ob es einen guten Grund gibt, dies nicht mehr für Konstanten zu verwenden.
  • const: Am besten für lokale Konstanten. Außerdem müssen Sie dies für eine verwenden, die Sie in einem Header deklariert haben und die Sie jetzt definieren.
  • static const: Am besten für dateispezifische (oder klassenspezifische) Konstanten.
  • extern const: Sie müssen dies verwenden, wenn Sie eine Konstante in einen Header exportieren.

Auch wenn Sie extern const, muss ich die Datei importieren, oder sind die Konstanten global verfügbar, ohne die Datei zu importieren?

Sie müssen die Datei entweder in jede Datei, in der Sie sie verwenden, oder in den Präfix-Header importieren.

384
Peter Hosey

FOUNDATION_EXPORT

Erwägen Sie die Verwendung von FOUNDATION_EXPORT für etwas mehr Kompatibilität als extern, da es in Foundation definiert ist und in kompatiblen Formaten für C, C++ und Win32 kompiliert wird.

Wie in NSObjCRuntime.h definiert

#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
8
Steve Moser