NSString 记录到带引号的控制台,有时

NSString logged to console with quotation marks, sometimes

背景

我在 NSDictionary 上创建了一个类别以便制作副本,并对所有键应用了特定的固定修改(在将我的对象映射到 Web 服务时使用):

@implementation NSDictionary (TransformKeys)

- (NSDictionary*) dictionaryByTransformingKeysWithBlock:(NSString* (^)(NSString* key))block
{
    NSMutableDictionary* transformedDictionary = [NSMutableDictionary new];

    for(NSString* key in [self allKeys]){

        // Transform the key string:
        NSString* transformedKey = block(key);

        // Copy value, using modified key in target dictionary:
        [transformedDictionary setObject:[self objectForKey:key]
                                  forKey:transformedKey];
    }

    return transformedDictionary;
}

@end

所以我可以映射(比如说)@{ @"userName" : @"John"}{@"UserName" : @"John"}

为了用作所述键转换的一部分,我还在 NSString 上定义了一个类别来提高第一个字符的大小写:

@implementation NSString (Camel)

- (NSString*) stringByCapitalizingFirstCharacter
{
    if ([self length] == 0){
        return @"";
    }

    NSString* firstCharacter = [self substringToIndex:1];

    firstCharacter = [firstCharacter uppercaseString];

    if ([self length] == 1) {
        return firstCharacter;
    }

    NSString* theRest = [self substringFromIndex:1];

    return [firstCharacter stringByAppendingString:theRest];
}

@end

当然,键是对象的 属性 名称,通过自省从 Objective-C 运行时获得。


问题:

当我打印到控制台时我的字典 - 或者它的 allKeys 数组,没关系 - 使用 NSLog(),一些键用引号括起来,而其他键打印为-是。

直接原因似乎是我正在按照两个不同的规则转换我的字典键,并且它们以某种方式打印不同:

  1. 如果我通过将第一个字符大写来转换我的键,它们将按原样打印:

    NSDictionary* convertedDictionary = [dictionary dictionaryByTransformingKeysWithBlock:^NSString *(NSString *key) {
    
        return [key stringByCapitalizingFirstCharacter];
    }];
    // -> Dictionary keys are printed to console as-is; i.e. UserName
    
  2. 如果我通过大写然后附加后缀来转换我的密钥,它们将被打印并括在双引号中:

    NSDictionary* convertedDictionary = [dictionary dictionaryByTransformingKeysWithBlock:^NSString *(NSString *key) {
    
        NSString* capitalized = [key stringByCapitalizingFirstCharacter];
    
        return  [capitalized stringByAppendingString:@"__c"];
    }];
    // -> Dictionary keys are printed to console in quotation marks; i.e. "UserName"
    

我确定这只是一个日志记录神器,实际的字符串中不包含 ",但这有点烦人。

有没有办法在控制台统一显示所有按键?我错过了什么吗?


更新

我将我的字典转换为 JSON(无论如何我最终都会这样做)并尝试记录它:

NSData* data = [NSJSONSerialization dataWithJSONObject:[dictionary allKeys]                                                    
                                               options:NSJSONWritingPrettyPrinted
                                                 error:nil];

NSLog(@"Keys: %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);

现在所有的键都统一用引号括起来(如预期的那样),所以这证实了我的数据在内部是预期的格式,并且不会因为日志中观察到的差异而出现问题...

虽然我无法用任何文档来支持这一点,但通过快速测试和大量时间查看日志,似乎任何包含非字母数字字符(包括空格)的键都将用双引号记录(这就是为什么你用 __ 后缀得到它)

所以,这个:

#import <Foundation/Foundation.h>

int main(int argc, char *argv[]) {
    @autoreleasepool {
        NSDictionary *dict = @{
            @"simple": @"",
            @"camelCase": @"",
            @"camelCaseWith__suffix": @"",
            @"camelCaseWith space": @"",
            @"camelCaseWith/special": @""
        };

        NSLog(@"%@", dict);
    }
}

将记录:

{
    camelCase = "";
    "camelCaseWith space" = "";
    "camelCaseWith/special" = "";
    "camelCaseWith__suffix" = "";
    simple = "";
}