Frage Präprozessor-Makrowert für Objective-C-Zeichenfolgenliteral


Ich habe ein Präprozessor-Makro in den Build-Einstellungen definiert

FOO=BAR

Diesen Wert möchte ich in ein Objective-C-String-Literal einfügen, das an eine Methode übergeben werden kann. Das folgende #define funktioniert nicht, aber es sollte demonstrieren, was ich erreichen möchte:

 #define FOOLITERAL @"FOO" //want FOOLITERAL to have the value of @"BAR"

 myMethodThatTakesAnNSString(FOOLITERAL);

Ich erwarte, dass ich das Offensichtliche irgendwie vermisse, aber ich kann nicht den richtigen Präprozessor-Voodoo finden, um zu bekommen, was ich brauche.


24
2017-09-30 04:08


Ursprung


Antworten:


Benutze die Zeichnungsoperator  # um eine C-Zeichenfolge aus dem Symbol zu machen. Aufgrund einer Eigenart des Präprozessors müssen Sie jedoch zwei zusätzliche Ebenen von Makros verwenden:

#define FOO BAR
#define STRINGIZE(x) #x
#define STRINGIZE2(x) STRINGIZE(x)
#define FOOLITERAL @ STRINGIZE2(FOO)
// FOOLITERAL now expands to @"BAR" 

Der Grund für die zusätzlichen Layer besteht darin, dass der Stringing-Operator nur für die Argumente des Makros und nicht für andere Tokens verwendet werden kann. Zweitens, wenn ein Argument eines Makros den Operator stringizing im Körper des Makros anwendet, dann ist dieses Argument nicht als ein weiteres Makro erweitert. Also, um das sicherzustellen FOO wird erweitert, wir wickeln in einem anderen Makro, so dass, wenn STRINGIZE2 wird erweitert, es erweitert sich auch FOO weil der stringizing-Operator nicht im Körper dieses Makros erscheint.


33
2017-09-30 04:19



Hier ist eine modifizierte Version von Adam Rosenfields Antwort mit klarer Semantik:

#define NSStringize_helper(x) #x
#define NSStringize(x) @NSStringize_helper(x)

Ich benutze es, um Code wie folgt zu ersetzen:

case OneEnumValue: name = @"OneEnumValue"; break;
case AnotherEnumValue: name = @"AnotherEnumValue"; break;

mit diesem:

#define case_for_type(type) case type: name = NSStringize(type); break

case_for_type(OneEnumValue);
case_for_type(AnotherEnumValue);

27
2018-02-04 01:09



Sie müssen Präprozessor Makro wie definieren,

FOO=\@\"BAR\"

Und benutze Codeseite wie,

[NSString stringWithFormat:@"macro: %@", FOO];

1
2017-08-17 11:31



Welchen Fehler siehst du genau? Diese Art von Sache funktioniert wie erwartet:

#define kMyString @"MyString"

[NSString stringWithFormat:@"macro: %@", kMyString];

-1
2017-09-30 04:12