Vorwort: Es lohnt sich, den Unterschied zwischen Precompiler-Direktiven und wahren Konstanten zu verstehen. A #define
führt nur eine Textersetzung durch, bevor der Compiler den Code erstellt. Dies funktioniert hervorragend für numerische Konstanten und typedefs, ist aber nicht immer die beste Idee für Funktions- oder Methodenaufrufe. Ich gehe davon aus, dass Sie wirklich eine echte Konstante haben wollen, dh der Code zum Erstellen des Suchpfades sollte nur einmal ausgeführt werden.
In Ihrer MyClass.m Datei, definieren Sie die Variable und füllt es in einer +initialize
Methode wie folgt:
static NSArray *documentsDir;
@implementation MyClass
+ (void) initialize {
if (documentsDir == nil) {
documentsDir = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES) lastObject] retain];
}
}
...
@end
Der static
Modifikator macht es sichtbar nur in der Zusammenstellung Einheit, wo es erklärt wird. Für eine einfache Konstante ist das alles, was Sie brauchen.
Wenn die Klasse Unterklassen hat, wird +initialize
für jede Unterklasse einmal aufgerufen werden (Standardeinstellung), so dass Sie überprüfen wollen werden, ob documentsDir
ist nil
vor ihm zuweisen, so dass Sie nicht Speicher dicht sind. (Oder, wie Peter Lewis hervorhebt, können Sie überprüfen, ob die gerade initialisierte Klasse die MyClass ist, entweder ==
oder die -isMemberOfClass:
-Methode.) Wenn die Unterklassen auch direkt auf die Konstante zugreifen müssen, müssen Sie sie vorher deklarieren die Variable als extern
in MyClass.h-Datei (die die untergeordneten Klassen enthalten):
extern NSArray *documentsDir;
@interface MyClass : NSObject
...
@end
Wenn Sie die Variable als extern vorge deklarieren, müssen Sie entfernen Sie das static
Schlüsselwort aus der Definition der Kompilierung zu vermeiden Fehler. Dies ist notwendig, damit die Variable mehrere Übersetzungseinheiten umfassen kann. (Ah, die Freuden des C ...)
Hinweis: In Objective-C-Code, der bessere Weg etwas wie extern
zu erklären ist OBJC_EXPORT
zu verwenden (a #define
in <objc/objc-api.h>
erklärt), die gesetzt basiert ob du C++ benutzt oder nicht. Ersetzen Sie einfach extern
durch OBJC_EXPORT
und Sie sind fertig.
Edit: ich zufällig auf einem related SO question.
Danke, aber wenn ich mein Projekt bauen, erhalte ich die folgende Warnung: 'searchPath' definiert ist, aber nicht verwendet. Die Warnung wird in allen Dateien angezeigt, außer in den Fällen, in denen sie einfach verwendet wird. Die Datei mit einer definierten Konstante ist in den vorkompilierten Headern enthalten. Gibt es eine Möglichkeit, diese Warnung los zu werden? Danke. –
Das liegt daran, dass das Symbol in mehrere Dateien importiert wird. Da die fragliche Datei in vielen anderen Dateien enthalten ist, verwenden Sie meine Anleitung zu Unterklassen - deklarieren Sie die Variable als extern in der Kopfzeile und wählen Sie dann nur eine Stelle (in einer .m-Datei) aus, um sie als statisch zu deklarieren (möglicherweise anders) Ort, um es zu initialisieren. Wenn Sie dies bereits tun und der Fehler weiterhin auftritt, setzen Sie die Variablendeklaration mit __attribute __ ((unused)) voran, um den Compiler anzuweisen, Warnungen über nicht verwendete Symbole zu unterdrücken. (Ich persönlich verwende #define UNUSED __attribute __ ((unused)) als Abkürzung dafür.) –
Beachten Sie, dass initialize mehrmals aufgerufen wird, wenn MyClass unterklassifiziert ist. Wenn Sie also initialize verwenden möchten, müssen Sie Folgendes verwenden: if (self == [Klasse MyClass]) { searchPath == ...; } –