NSJSONSerialization生成NSCFString*和NSTaggedPointerString*

18
执行NSJSONSerialization对以下json的操作,有时会返回NSCFString*和NSTaggedPointerString*字符串值。是否有人知道为什么会这样,并且NSJSONSerialization使用什么来确定返回哪种类型?
jsonData = [NSJSONSerialization JSONObjectWithData:data
                                                   options:kNilOptions
                                                     error:&parseError];

    {
      "UserPermissionsService": {
        "ServiceHeader": {}, 
        "UserApplicationPermissions": {
          "ApplicationPermissions": {
            "ApplicationID": "TEST", 
            "Permission": [
              {
                "Locations": [
                  "00000"
                ], 
                "PermissionID": "LOGIN"
              }, 
              {
                "Locations": [
                  "00000"
                ], 
                "PermissionID": "SALES_REPORT_VIEW"
              }
            ]
          }
        }
      }
    }

"

LOGIN"返回的是NSTaggedPointerString*。"SALES_REPORT_VIEW"返回的是NSCFString*。这会影响到我在使用和转换值时的下游操作。

更新

我了解到...

"当整个值可以保持在指针本身中而不需要分配任何数据时,就会出现NSTaggedPointerString。"

这里有一个详细的解释...

"

https://www.mikeash.com/pyblog/friday-qa-2015-07-31-tagged-pointer-strings.html

由于NSTaggedPointerString是NSString的子类,因此在使用数据时,显示引号/不显示引号对我来说永远不应该成为问题。

感谢所有发表评论的人。我很满意我理解了NSJSONSerialization正在做什么。


1
你在做什么能有所不同吗?你总是得到一个NSString。哪个NSString的子类对你来说永远不重要。 - gnasher729
3
搜索 NSTaggedPointerString。如果这对您有所影响,那么您正在做一些非常、非常错误的事情。在64位系统上,当整个值可以保留在指针本身中而不分配任何数据时,标记指针对于小值非常常见。 - gnasher729
1
@Justin Domnitz 我不认为你在正确的轨道上,请添加一个使用这些值或它们的类型的示例。 - A-Live
1
我觉得我们有点跑题了。 :) 我只是想理解我从NSJSONSerialization得到的结果。关于系统确定“当整个值可以在指针本身中保持而不分配任何数据时,NSTaggedPointerString结果”的最佳答案似乎来自gnasher729。有人能指引我查看相关文档吗?谷歌没有提供有用的信息(这就是我在这里发布问题的原因)。 - Justin Domnitz
3
@gnasher729,有人在stackoverflow上提问,结果却收到更多的问题,真是太好笑了。另外,Justin如果找到答案,请创建一个答案并标记为已解决。例如,当NSJSONSerialization混淆字典键作为NSTaggedPointerStrings时,我就会遇到问题,除非将它们显式地转换,否则无法访问这些值,这使得索引看起来很不舒服。 - Michael Lorenzo
显示剩余2条评论
2个回答

1

Foundation的许多功能都是以类群的形式实现的。简而言之,您可以将其视为NSString进行交互,但基础框架会根据实际内容更改后端实现,以优化某些性能或空间特征。

如果您感到好奇,Foundation团队中的一位成员在iOS 11时候列出了类群列表,此处可查看。


0

我通过使用“MUTABLECOPY”修复了它

我遇到了同样的问题。显然,苹果为了某种“性能”机制,对于“众所周知”的字符串(例如“加利福尼亚”),使用NSTaggedPointerString,但这可能会成为一个问题,因为由于某种奇怪的原因,NSJSONSerialization不会在这种类型的字符串周围添加引号。解决方法很简单:

NSString *taggedString = @"California";
[data setObject:[taggedString mutableCopy] forKey:@"state"]

非常好用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接