Frage Konstanten in Objective-C


Ich entwickle ein Kakao Anwendung, und ich verwende Konstante NSStrings als Möglichkeiten zum Speichern von Schlüsselnamen für meine Einstellungen.

Ich verstehe, dass dies eine gute Idee ist, weil es einen einfachen Schlüsselwechsel bei Bedarf ermöglicht. Plus, es ist das Ganze "trennen Sie Ihre Daten von Ihrer Logik" Begriff.

Wie auch immer, gibt es eine gute Möglichkeit, diese Konstanten für die gesamte Anwendung einmal zu definieren? Ich bin mir sicher, dass es einen einfachen und intelligenten Weg gibt, aber im Moment definieren meine Klassen einfach die, die sie benutzen.


969
2018-02-11 21:52


Ursprung


Antworten:


Sie sollten eine Header-Datei wie erstellen

// Constants.h
FOUNDATION_EXPORT NSString *const MyFirstConstant;
FOUNDATION_EXPORT NSString *const MySecondConstant;
//etc.

(Sie können verwenden extern Anstatt von FOUNDATION_EXPORT wenn Ihr Code nicht in gemischten C / C ++ - Umgebungen oder auf anderen Plattformen verwendet wird)

Sie können diese Datei in jede Datei einfügen, die die Konstanten verwendet, oder in den vorkompilierten Header für das Projekt.

Sie definieren diese Konstanten in einer .m Datei wie

// Constants.m
NSString *const MyFirstConstant = @"FirstConstant";
NSString *const MySecondConstant = @"SecondConstant";

Constants.m sollte dem Ziel Ihrer Anwendung / Ihres Frameworks hinzugefügt werden, damit es mit dem endgültigen Produkt verknüpft wird.

Der Vorteil der Verwendung von String-Konstanten anstelle von #define'd Konstanten ist, dass Sie mit Zeigervergleich auf Gleichheit testen können (stringInstance == MyFirstConstant) das ist viel schneller als String-Vergleich ([stringInstance isEqualToString:MyFirstConstant]) (und einfacher zu lesen, IMO).


1236
2018-02-11 22:38



Einfachster Weg:

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

Besserer Weg:

// Prefs.h
extern NSString * const PREFS_MY_CONSTANT;

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

Ein Vorteil der zweiten besteht darin, dass das Ändern des Werts einer Konstanten nicht zu einer Neuerstellung Ihres gesamten Programms führt.


264
2018-02-11 22:02



Es gibt auch eine Sache zu erwähnen. Wenn Sie eine nicht globale Konstante benötigen, sollten Sie verwenden static Stichwort.

Beispiel

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

Wegen dem static Schlüsselwort, dieses const ist außerhalb der Datei nicht sichtbar.


Geringfügige Korrektur durch @QuinnTaylor: Statische Variablen sind innerhalb von a sichtbar Kompilierungseinheit. Normalerweise ist dies eine einzelne .m-Datei (wie in diesem Beispiel), aber sie kann Sie beißen, wenn Sie sie in einer Kopfzeile deklarieren, die an anderer Stelle enthalten ist, da Sie nach der Kompilierung Linker-Fehler erhalten


182
2018-02-12 16:28



Die akzeptierte (und korrekte) Antwort besagt, dass "Sie diese [Constants.h] -Datei in den vorkompilierten Header für das Projekt einfügen können."

Als Neuling hatte ich Schwierigkeiten, dies ohne weitere Erklärungen zu tun - hier ist wie: In Ihrer YourAppNameHere-Prefix.pch-Datei (das ist der Standardname für den vorkompilierten Header in Xcode), importieren Sie Ihre Constants.h innerhalb der #ifdef __OBJC__ Block.

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

Beachten Sie auch, dass die Dateien Constants.h und Constants.m absolut nichts anderes enthalten sollten als das, was in der akzeptierten Antwort beschrieben ist. (Keine Schnittstelle oder Implementierung).


117
2017-09-18 14:08



Ich benutze generell den Weg von Barry Wark und Rahul Gupta.

Obwohl ich nicht die gleichen Wörter in beiden h und m-Datei wiederholen möchte. Beachten Sie, dass im folgenden Beispiel die Zeile in beiden Dateien fast identisch ist:

// file.h
extern NSString* const MyConst;

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

Daher möchte ich einige C-Präprozessor-Maschinen verwenden. Lassen Sie mich das Beispiel erklären.

Ich habe eine Header-Datei, die das Makro definiert 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

In meinem .h / .m Paar, wo ich die Konstante definieren möchte, mache ich folgendes:

// 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, ich habe alle Informationen über die Konstanten nur in der .h-Datei.


50
2017-12-02 21:53



Eine kleine Änderung des Vorschlags von @Krizz, damit es richtig funktioniert, wenn die Konstanten-Header-Datei in den PCH aufgenommen werden soll, was eher normal ist. Da das Original in den PCH importiert wird, wird es nicht erneut in den PCH geladen .m Datei und damit bekommst du keine Symbole und der Linker ist unglücklich.

Die folgende Änderung ermöglicht jedoch, dass es funktioniert. Es ist ein wenig verworren, aber es funktioniert.

Du brauchst 3 Dateien, .h Datei, die die konstanten Definitionen hat, die .h Datei und die .m Datei, werde ich verwenden ConstantList.h, Constants.h und Constants.m, beziehungsweise. Die Inhalte von Constants.h sind einfach:

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

und das Constants.m Datei sieht so aus:

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

Endlich, das ConstantList.h Datei enthält die tatsächlichen Deklarationen und das ist alles:

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

Ein paar Dinge zu beachten:

  1. Ich musste das Makro neu definieren .m Datei nach  #undefes für das Makro zu verwenden.

  2. Ich musste es auch benutzen #include Anstatt von #import Damit dies ordnungsgemäß funktioniert und der Compiler die zuvor vorkompilierten Werte nicht sehen kann.

  3. Dies erfordert eine Neukompilierung Ihrer PCH (und wahrscheinlich des gesamten Projekts), wenn Werte geändert werden, was nicht der Fall ist, wenn sie wie üblich getrennt (und dupliziert) sind.

Hoffe das ist hilfreich für jemanden.


25
2017-12-03 00:03



Ich habe selbst eine Kopfzeile, die dazu dient, konstante NSStrings zu deklarieren, die für Präferenzen wie folgt verwendet werden:

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

Dann deklarieren Sie sie in der begleitenden .m-Datei:

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";

Dieser Ansatz hat mir gut getan.

Bearbeiten: Beachten Sie, dass dies am besten funktioniert, wenn die Zeichenfolgen in mehreren Dateien verwendet werden. Wenn nur eine Datei es verwendet, können Sie einfach tun #define kNSStringConstant @"Constant NSString" in der M-Datei, die die Zeichenfolge verwendet.


24
2018-01-26 23:15



// Prefs.h
extern NSString * const RAHUL;

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

14
2017-09-28 04:37