【问题标题】:NSString logged to console with quotation marks, sometimesNSString 有时用引号记录到控制台
【发布时间】:2016-07-26 15:02:42
【问题描述】:

背景

我在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 运行时内省获得的对象的属性名称。


问题:

当我使用NSLog() 将我的字典或它的allKeys 数组打印到控制台时,一些键用引号括起来,而另一些键则按原样打印。

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

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

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

【问题讨论】:

  • 这是众所周知的,有几个问题。
  • 对不起,我没有通过搜索找到它们。随意指出重复的目标 abd 我会检查一下。
  • 我认为他们很难找到,我怀疑他们是否真的解决了你的一致性问题。但是目前尚不清楚实际问题是什么?这是一个强迫症问题,因为您肯定无法进一步处理记录的输出吗?
  • 虽然我无法用任何文档来支持这一点,但从快速测试和大量时间查看日志来看,似乎任何包含非字母数字字符(包括空格)的键都会被记录用双引号(这就是为什么你用你的__ 后缀得到它)......
  • 了解发生了什么既是强迫症,也是好奇心(即,是NSLog 的事情还是NSString 的一些内部细节)。

标签: objective-c nsstring nslog


【解决方案1】:

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

所以,这个:

#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 = "";
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-12
    • 1970-01-01
    相关资源
    最近更新 更多