【问题标题】:Printing an NSString打印一个 NSString
【发布时间】:2010-02-07 07:20:17
【问题描述】:

在 Objective-C 中打印 NSString 的正确方法是什么?很多示例使用 NSLog(),但根据文档:

NSLog 是一个 FoundationKit 函数,用于将调试语句打印到控制台。 ... NSLog 的工作原理基本上是: fprintf(stderr, format_string, args ...);

这对我来说有点像 Win32/C++ 中的 _TRACE 宏。我不想打印到标准错误,我想打印到标准输出。有人建议使用 printf() 如下:

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

但这似乎是间接打印 NSString 的额外级别,并且它不像解决方案那样“感觉”。

【问题讨论】:

    标签: objective-c


    【解决方案1】:

    在 Cocoa 中向stdout 发送内容实际上是一件非常罕见的事情,因为几乎所有项目本质上都是 GUI。构建为命令行工具或需要处理stdout 的项目相对较少。

    但是,基金会确实提供了写入标准输出的方法。具体来说,NSFileHandle 具有fileHandleWithStandardOutput,它为您提供了一个可以写入stdout 的文件句柄。

    从那里开始,将NSString 转换为NSData 并编写它。

    相当多的步骤,但很容易封装在一个可重用的函数中:

    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];
    }
    

    【讨论】:

    • NSNEXTSTEPStringEncoding?
    • 抱歉唠叨,但是如何在这样的日志行之间插入'\n'?不想在这样的日志记录设施中浪费太多的周期。
    • 啊,也许你知道为什么其他方法(使用 prinff("%s\n", [formattedString UTFString]) 会在我的打印行中发出各种垃圾?
    • 可能是因为您将 unicode 字符串传递给期望 ASCII 字符串的东西。如果您使用的是 printf,只需打印一个换行符。反正性能已经很差了。
    【解决方案2】:

    解决方案。

    由于printf 是一个纯C 函数,它不会识别Objective-C 对象。 (NSLog 的格式化程序不同于 printf 的格式化程序。)因此,您必须在格式化之前将其转换为 C 字符串。

    顺便说一句,您可以使用[str UTF8String] 而不是[str cStringUsingEncoding:NSUTF8StringEncoding]

    【讨论】:

    • 我知道printf 是一个纯 C 函数,但我觉得很奇怪你必须用它来打印一个 NSString,而不是 Core Foundation 有一个文本 IO 库。
    【解决方案3】:

    C 字符串 (UTF8String) 是指向字符串对象内部结构的指针。

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

    【讨论】:

      【解决方案4】:

      我认为您会发现这些足以满足您的需求:

      // 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
      }
      

      【讨论】:

        【解决方案5】:

        您应该使用自定义文件处理程序或自己编写宏。

        提示:当 NSLog 打印出一个对象时,它使用对象的debugDescription 方法。您可以为您的自定义 NSObject 子类覆盖此方法,以将自定义 debugInfo 打印到标准输出。

        【讨论】:

        • 太棒了!绝对不知道。
        【解决方案6】:

        我只是这样做:

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

        然后我可以将它用作:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-06-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多