2010-02-07 4 views
27

Quelle est la méthode correcte pour imprimer un NSString en Objective-C? De nombreux exemples utilisent NSLog(), mais selon la documentation:Impression d'un NSString

NSLog est une fonction FoundationKit permettant d'imprimer des instructions de débogage sur la console. ... NSLog fonctionne essentiellement comme: fprintf (stderr, format_string, args ...);

Ce qui pour moi est un peu comme la macro _TRACE dans Win32/C++. Je ne veux pas imprimer sur stderr, je veux imprimer sur stdout. Il y a des gens qui suggèrent d'utiliser le printf() comme suit:

printf("%s", [str cStringUsingEncoding:NSUTF8StringEncoding]); 

Mais cela semble être un niveau supplémentaire sur indirection pour obtenir le NSString imprimé, et il n'a pas « sentir » comme la solution.

Répondre

24

Bien cette est la solution.

Puisque printf est une fonction C pure, il ne reconnaîtra pas les objets Objective-C. (Le formateur de NSLog est distinct de celui de printf.) Par conséquent, vous devez le convertir en une chaîne C avant le formatage. Par ailleurs, vous pouvez utiliser [str UTF8String] au lieu de [str cStringUsingEncoding:NSUTF8StringEncoding].

+5

Je comprends 'printf' est une pure fonction C, mais je trouve ça bizarre que vous avez pour l'utiliser pour imprimer un NSString, plutôt que Core Foundation ayant une bibliothèque d'E/S texte. –

3

Vous devez utiliser le gestionnaire de fichiers personnalisé ou écrire vous-même une macro. Astuce: lorsque NSLog imprime un objet, il utilise la méthode debugDescription de l'objet. Vous pouvez remplacer cette méthode pour vos sous-classes personnalisées NSObject pour imprimer le fichier debugInfo personnalisé sur stdout.

+0

Génial! Je ne le savais certainement pas. –

29

Spewing stuff à stdout est en fait une chose assez rare à faire dans Cocoa, étant donné que presque tous les projets sont GUI dans la nature. Il y a relativement peu de projets qui sont construits comme des outils de ligne de commande ou doivent traiter stdout autrement. Cependant, la Fondation fournit les moyens d'écrire sur stdout. Plus précisément, NSFileHandle a fileHandleWithStandardOutput qui vous donne un handle de fichier qui peut écrire à stdout. De là, il s'agit de convertir le NSString en NSData et de l'écrire.

Tout à fait quelques pas, mais facilement enveloppé dans une fonction réutilisable:

void MyLog(NSString *format, ...) { 
    va_list args; 
    va_start(args, format); 
    NSString *formattedString = [[NSString alloc] initWithFormat: format 
                arguments: args]; 
    va_end(args); 
    [[NSFileHandle fileHandleWithStandardOutput] 
     writeData: [formattedString dataUsingEncoding: NSNEXTSTEPStringEncoding]]; 
    [formattedString release]; 
} 
+0

Merci pour l'exemple –

+2

NSNEXTSTEPStringEncoding? – Trejkaz

3

Je pense que vous trouverez ces suffisant pour vos besoins:

// print to stdout 
static void NSPrint(NSString *format, ...) { 
    va_list args; 
    va_start(args, format); 

    NSString *string = [[NSString alloc] initWithFormat:format arguments:args]; 

    va_end(args); 

    fprintf(stdout, "%s\n", [string UTF8String]); 

#if !__has_feature(objc_arc) 
    [string release]; 
#endif 
} 

// print to stderr 
static void NSPrintErr(NSString *format, ...) { 
    va_list args; 
    va_start(args, format); 

    NSString *string = [[NSString alloc] initWithFormat:format arguments:args]; 

    va_end(args); 

    fprintf(stderr, "%s\n", [string UTF8String]); 

#if !__has_feature(objc_arc) 
    [string release]; 
#endif 
} 
3

chaîne C (UTF8String) est un pointeur vers une structure à l'intérieur de l'objet chaîne.

NSString *str = @"Hello, World."; 
printf("%s\n", [str UTF8String]); 
0

Je fais juste:

define NSPrintf(...) printf("%s", [[NSString stringWithFormat: __VA_ARGS__] UTF8String]) 

je peux alors utiliser comme:

NSPrintf(@"Sorry %@, I can't do that\n", name);