【问题标题】:.Net vs Cocoa String Formats.Net vs Cocoa 字符串格式
【发布时间】:2011-01-20 16:18:23
【问题描述】:

我可以重现以下 C#/.NET:

//A
String.Format("There are {0} cats in my {1} and no {2}", 2, "house", "dogs");

在 Objective-C/Cocoa 中:

//B
[NSString stringWithFormat:@"There are %d cats in my %@ and no %@", 2, "house", "dogs"];

但我不能这样做:

//C
String.Format("I have {0} dogs in my house.  My {0} dogs are very nice, but it is hard to walk {0} dogs at the same time.", numDogs);

在 Objective-C 中:

//D
[NSString stringWithFormat:@"I have %d dogs in my house.  My %d dogs are very nice, but it is hard to walk %d dogs at the same time.", numDogs];

因为它使用 printf 格式或其他格式。有没有更高级的方法来做到这一点?有没有办法在字符串解析中做 KVC?

这在技术上是我想要的:

[player setValue:@"Jimmy" forKey@"PlayerName"];
//later
[NSString stringWithMagicFormat:@"<PlayerName> sat on a bench in the middle of winter, and <GenderPronoun> felt very cold." andPlayer:player];
// or
[NSString stringwithMagicFormat: playerEnteredStringWithTagInIt andPlayer:player];

但我会接受:

String.Format(playerEnteredStringWithTagInIt, player.PlayerName, player.PlayerGender, player.GenderPronoun, ...);

谢谢,

【问题讨论】:

    标签: c# .net objective-c cocoa string-formatting


    【解决方案1】:
    [NSString stringWithFormat:@"I have %1$d dogs in my house.  My %1$d dogs are very nice, but it is hard to walk %1$d dogs at the same time.", numDogs];
    

    (见man 3 printf。)

    【讨论】:

    • +1 互联网 DUH。如果没有人发布有关 KVC 的任何内容,我会接受。
    • 为什么需要这样?不能用gnu99吗?如果您正在为 OS X 进行编译(我假设这是因为您将其标记为“可可”),OS X 手册页没有那个警告。
    • (Dang,我想删除“为什么”,因为它听起来很疯狂,但我不能了。)
    • 虽然在宏中使用语法扩展对于某些代码用户来说可能是个问题,但不能使用 C99 未指定的 [NSString stringWithFormat:] 格式参数。我的意思是,%@ 也不在 C99 中。
    【解决方案2】:

    如果您使用的是NSStringstringWithFormat:,那么我认为C99 合规性并不真正适用:虽然stringWithFormat:printf 相似,但它有自己的实现已经存在了一会儿。

    NSLocalizedString() 宏实际上会自动为您执行此操作。例如,假设我有以下代码:

     @implementation MDAppController
    
    - (id)init {
        if (self = [super init]) {
            NSArray *catsArray = [NSArray array];
            NSString *string = [NSString stringWithFormat:
             NSLocalizedString(@"There are %lu %@ %@ in my home.", @"no comment"),
            (unsigned long)[catsArray count],
                                NSLocalizedString(@"red", @""),
                                NSLocalizedString(@"cats", @"")];
            NSLog(@"string == %@", string);
        }
        return self;
    }
    
    @end
    

    如果我随后在终端中运行以下命令

    /usr/bin/genstrings ~/Developer/NSLocalizedString/MDAppController.m -o ~/Desktop/Strings

    (虽然我更喜欢将窗口标题栏中的代理图标拖到我保留在 Dock 中的 AppleScript 小滴上:GenerateStrings.app。它(过度)将生成的 .strings 文件写入 ~/Desktop/Strings/(创建如有必要)。您可以通过将脚本拖放到 AppleScript 编辑器来编辑脚本)。

    它将生成一个 UTF16 Localizable.strings 文件,您可以将其添加到您的项目中。其中将包含以下内容:

    English.lproj/Localizable.strings

    /* No comment provided by engineer. */
    "cats" = "cats";
    
    /* No comment provided by engineer. */
    "red" = "red";
    
    /* no comment */
    "There are %lu %@ %@ in my home." = "There are %1$lu %2$@ %3$@ in my home.";
    

    将其复制到西班牙语项目子文件夹并根据需要更改项目的顺序(因为在西班牙语中,形容词通常位于名词之后):

    Spanish.lproj/Localizable.strings

    /* No comment provided by engineer. */
    "cats" = "gatos";
    
    /* No comment provided by engineer. */
    "red" = "rojos";
    
    /* no comment */
    "There are %lu %@ %@ in my home." = "Está %1$lu %3$@ %2$@ en mi casa.";
    

    当英语是我在语言和文本首选项窗格中的主要(最顶层)语言时:

    1/20/2011 12:59:37 PM NSLocalizedString[1777] string == There are 0 red cats in my home.

    当西班牙语是我在语言和文本首选项窗格中的主要(最顶层)语言时:

    1/20/2011 12:37:02 PM NSLocalizedString[1702] string == Está 0 gatos rojos en mi casa.

    .strings 文件在某种意义上是键值对。

    欲了解更多信息,请参阅Resource Programming Guide: String Resources

    【讨论】:

      【解决方案3】:

      我喜欢每个人的答案,但我只在 Docs 中花了 15 分钟,就找到了我正在寻找的答案……叹息,RTM!这是我的解决方案,以防其他人正在寻找类似的东西。

      // Put this in a category of NSString
      - (NSString*) stringByReplacingOccurrencesOfKeysWithValues:(NSDictionary*)keyValuePairs
      {
          NSString *fStr = self;
          if (keyValuePairs) {
              for (NSString *key in [keyValuePairs allKeys]) {
                  NSString *value = [NSString stringWithFormat:@"%@",[keyValuePairs valueForKey:key]];
                  fStr = [fStr stringByReplacingOccurrencesOfString:key withString:value];
              }
          }
          return fStr;
      }
      

      似乎工作正常,这是我的测试代码:

      // testing NSString+Keys
      NSMutableDictionary *mud = [NSMutableDictionary dictionaryWithCapacity:1];
      [mud setValue:@"Jimmy" forKey:@"{PlayerName}"];
      [mud setValue:[NSNumber numberWithInt:97] forKey:@"{HitPoints}"];
      [mud setValue:[NSNumber numberWithFloat:1.0678f] forKey:@"{meters}"];
      NSString *mystr = [@"Help me {PlayerName} before it is too late! I only have {HitPoints}hp left!  And I am {meters}m away! {PlayerName} hurry!" stringByReplacingOccurrencesOfKeysWithValues:mud];
      NSLog(mystr);
      

      输出是:

      在为时已晚之前帮助我吉米!我只剩下97hp了!而我在 1.0678m 之外!吉米快点!

      【讨论】:

        猜你喜欢
        • 2011-07-02
        • 1970-01-01
        • 1970-01-01
        • 2011-10-15
        • 1970-01-01
        • 2012-03-08
        • 1970-01-01
        • 2019-03-04
        相关资源
        最近更新 更多