9

Ich entwickle eine statische Bibliothek, die an andere Entwickler verteilt wird, die möglicherweise Debug-Anweisungen benötigen. Also habe ich mehrere Ebenen der Protokollierung.Wie bekomme ich einen formatierten NSString aus Format und va_list?

Um eine konstante Auftreten von

if(loggingLevelCurrentlySet >= loggingLevelWantedForThisInstance){ 
    NSLog(@"log this"); 
} 

zu vermeiden, habe ich eine Reihe von Logging-Funktion Wrapper. Eine vereinfachte Version sieht wie folgt aus:

void myLog(int logLevel, NSString *format, va_list args){ 
    if((loggingLevelCurrentlySet >= logLevel)){ 
     NSLogv(format, args); 
    } 
} 

void myLogLevel1(NSString *format, ...){ 
    va_list args; 
    va_start(args, format); 

    myLog(1, format, args); 
    va_end(args); 
} 

void myLogLevel2(NSString *format, ...){ 
    va_list args; 
    va_start(args, format); 

    myLog(2, format, args); 
    va_end(args); 
} 

usw.

Aber jetzt, ich will, aus myLog, Zugriff auf die voll Formatierter String etwas anderes zu tun.

void myLog(int logLevel, NSString *format, va_list args){ 
     NSString *fullString = [NSString stringWithFormat:format, args]; //crashes when args is anything but an empty list 
     CFStringRef cfsr = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, format, args); //also crashes 

     //want to use the string here 

     if((loggingLevelCurrentlySet >= logLevel)){ 
      NSLogv(format, args); 
     } 
} 

Antwort

13
NSString *fullString = [[[NSString alloc] initWithFormat:format arguments:args] autorelease]; 

Es gibt ein Verfahren für das;)

Obwohl ich nicht den Eindruck erwecken Funktionen zu verwenden, aber einige einfache Makro-Definitionen:

#define myLogLevel1(format, ...) myLog(1, format, __VA_ARGS__) 
#define myLogLevel2(format, ...) myLog(2, format, __VA_ARGS__) 
+0

Dank. Was ist der Grund, warum die Shortcut-Klassenmethode nicht funktioniert? – executor21

+0

In (Objective-) C ist es möglich, eine Liste von Argumenten variabler Länge in einer solchen 'va_list' zu erfassen, aber Sie können sie nie wieder verwenden, während Sie ein anderes Objekt aufrufen. Es wird einfach nicht funktionieren, sehr nervig. Durch die Verwendung des Makros wird der Präprozessor sie jedoch korrekt behandeln und es wird so kompiliert, als ob Sie einfach 'myLog (1, format, arg1, arg2, arg3);' eingegeben hätten, damit das funktioniert. Es ist noch schneller, da kein zusätzlicher Code zur Laufzeit ausgeführt werden muss. – Joost

Verwandte Themen