Ich entwickle eine Cocoa- Anwendung und verwende Konstante NSString
s, um Schlüsselnamen für meine Einstellungen zu speichern.
Ich verstehe, dass dies eine gute Idee ist, da es bei Bedarf ein einfaches Wechseln der Schlüssel ermöglicht.
Außerdem ist es der ganze Begriff "Trennen Sie Ihre Daten von Ihrer Logik".
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 nur die, die sie verwenden.
Antworten:
Sie sollten eine Header-Datei wie erstellen
(Sie können
extern
anstelle von verwenden,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 aufnehmen, die die Konstanten verwendet, oder in den vorkompilierten Header für das Projekt.
Sie definieren diese Konstanten in einer .m-Datei wie
Constants.m sollte dem Ziel Ihrer Anwendung / Ihres Frameworks hinzugefügt werden, damit es mit dem Endprodukt verknüpft wird.
Der Vorteil der Verwendung von Zeichenfolgenkonstanten anstelle von
#define
'd-Konstanten besteht darin, dass Sie die Gleichheit mithilfe des Zeigervergleichs (stringInstance == MyFirstConstant
) testen können, der viel schneller als der Zeichenfolgenvergleich ([stringInstance isEqualToString:MyFirstConstant]
) ist (und einfacher zu lesen ist, IMO).quelle
NSString
Eigenschaften mitcopy
anstelle von definierenretain
. Als solche könnten (und sollten) sie eine andere Instanz IhrerNSString*
Konstanten halten, und ein direkter Vergleich der Speicheradressen würde fehlschlagen. Außerdem würde ich davon ausgehen, dass jede einigermaßen optimale Implementierung von auf-isEqualToString:
Zeigergleichheit prüfen würde, bevor auf den Kern des Zeichenvergleichs eingegangen wird.Einfachster Weg:
Besserer Weg:
Ein Vorteil des zweiten ist, dass das Ändern des Werts einer Konstante nicht zu einer Neuerstellung Ihres gesamten Programms führt.
quelle
extern NSString const * const MyConstant
, dh es ist ein konstanter Zeiger auf ein konstantes Objekt und nicht nur ein konstanter Zeiger?Es gibt auch eine Sache zu erwähnen. Wenn Sie eine nicht globale Konstante benötigen, sollten Sie das
static
Schlüsselwort verwenden.Beispiel
Aufgrund des
static
Schlüsselworts ist diese Konstante außerhalb der Datei nicht sichtbar.Kleinere Korrektur durch @QuinnTaylor : Statische Variablen sind in einer Kompilierungseinheit sichtbar . Normalerweise ist dies eine einzelne .m-Datei (wie in diesem Beispiel), aber sie kann Sie beißen, wenn Sie sie in einem Header deklarieren, der an anderer Stelle enthalten ist, da nach dem Kompilieren Linkerfehler auftreten
quelle
Die akzeptierte (und korrekte) Antwort lautet: "Sie können diese [Constants.h] -Datei ... in den vorkompilierten Header für das Projekt aufnehmen."
Als Anfänger hatte ich Schwierigkeiten, dies ohne weitere Erklärung zu tun - so geht's: Importieren Sie in Ihrer YourAppNameHere-Prefix.pch-Datei (dies ist der Standardname für den vorkompilierten Header in Xcode) Ihre Constants.h in den
#ifdef __OBJC__
Block .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).
quelle
Ich benutze im Allgemeinen den Weg von Barry Wark und Rahul Gupta.
Obwohl ich es nicht mag, die gleichen Wörter sowohl in der .h- als auch in der .m-Datei zu wiederholen. Beachten Sie, dass im folgenden Beispiel die Zeile in beiden Dateien nahezu identisch ist:
Daher verwende ich gerne einige C-Präprozessor-Maschinen. Lassen Sie mich anhand des Beispiels erklären.
Ich habe eine Header-Datei, die das Makro definiert
STR_CONST(name, value)
:In meinem .h / .m-Paar, in dem ich die Konstante definieren möchte, mache ich Folgendes:
et voila, ich habe alle Informationen über die Konstanten nur in der .h-Datei.
quelle
Ich selbst habe einen Header, der dazu dient, konstante NSStrings zu deklarieren, die für folgende Einstellungen verwendet werden:
Dann deklarieren Sie sie in der zugehörigen .m-Datei:
Dieser Ansatz hat mir gute Dienste geleistet.
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 dies einfach
#define kNSStringConstant @"Constant NSString"
in der .m-Datei tun , die die Zeichenfolge verwendet.quelle
Eine geringfügige Änderung des Vorschlags von @Krizz, damit er ordnungsgemäß 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 sodass Sie keine Symbole erhalten und der Linker unglücklich ist.Mit der folgenden Änderung kann es jedoch funktionieren. Es ist ein bisschen verworren, aber es funktioniert.
Sie benötigen drei Dateien,
.h
Datei , die die Konstanten - Definitionen, die hat.h
Datei und die.m
Datei, werde ich verwendenConstantList.h
,Constants.h
undConstants.m
, respectively. Der Inhalt vonConstants.h
ist einfach:und die
Constants.m
Datei sieht aus wie:Schließlich enthält die
ConstantList.h
Datei die tatsächlichen Deklarationen und das ist alles:Ein paar Dinge zu beachten:
Ich musste das Makro in der
.m
Datei neu definieren, nachdem ich#undef
es für das zu verwendende Makro verwendet hatte.Ich musste
#include
stattdessen auch verwenden,#import
damit dies richtig funktioniert und der Compiler die zuvor vorkompilierten Werte nicht sieht.Dies erfordert eine Neukompilierung Ihres PCH (und wahrscheinlich des gesamten Projekts), wenn Werte geändert werden. Dies ist nicht der Fall, wenn sie wie gewohnt getrennt (und dupliziert) werden.
Hoffe das ist hilfreich für jemanden.
quelle
extern
oben genannten durch die ersetzen würdenFOUNDATION_EXPORT
.quelle
Wie Abizer sagte, könnten Sie es in die PCH-Datei einfügen. Eine andere Möglichkeit, die nicht so schmutzig ist, besteht darin, eine Include-Datei für alle Ihre Schlüssel zu erstellen und diese dann entweder in die Datei aufzunehmen, in der Sie die Schlüssel verwenden, oder sie in den PCH aufzunehmen. Wenn Sie sie in ihrer eigenen Include-Datei haben, haben Sie mindestens einen Ort, an dem Sie alle diese Konstanten suchen und definieren können.
quelle
Wenn Sie so etwas wie globale Konstanten wollen; Ein schneller und schmutziger Weg besteht darin, die konstanten Deklarationen in die
pch
Datei einzufügen.quelle
Versuchen Sie es mit einer Klassenmethode:
Ich benutze es manchmal.
quelle
isEqualToString:
für den Vergleich verwenden müssen weitere Kosten zur Laufzeit. Wenn Sie Konstanten möchten, erstellen Sie Konstanten.Wenn Sie eine Namespace-Konstante mögen, können Sie struct nutzen. Freitag, Fragen und Antworten 2011-08-19: Namespaced-Konstanten und -Funktionen
quelle
__unsafe_unretained
Qualifikationsmerkmal voranstellen , damit es funktioniert.Ich verwende eine Singleton-Klasse, damit ich die Klasse verspotten und die Konstanten bei Bedarf zum Testen ändern kann. Die Konstantenklasse sieht folgendermaßen aus:
Und es wird so verwendet (beachten Sie die Verwendung einer Kurzform für die Konstanten c - es spart
[[Constants alloc] init]
jedes Mal die Eingabe ):quelle
Wenn Sie so etwas
NSString.newLine;
von Ziel c aus aufrufen möchten und möchten, dass es statisch konstant ist, können Sie so etwas in Kürze erstellen:Und Sie haben eine gut lesbare Konstantendefinition, die innerhalb eines Typs Ihrer Wahl verfügbar ist, während der Stil an den Kontext des Typs gebunden ist.
quelle