【问题标题】:"NSString stringWithUTF8String:" is overly touchy“NSString stringWithUTF8String:”过于敏感
【发布时间】:2011-06-07 09:34:50
【问题描述】:

我正在使用高级 Cocoa 功能(例如 NSStringNSData)进行一些字符串操作,而不是深入到 C 级别的事情(例如处理 chars 的数组)。

出于对它的喜爱,+[NSString stringWithUTF8String:]sometimes 返回nil,这是一个非常好的字符串,该字符串最初是用-[NSString UTF8String] 创建的。人们会假设当输入格式错误时会发生这种情况。以下是输入失败的示例,以十六进制表示:

55 6B 66 51 35 59 4A 5C 6A 60 40 33 5F 45 58 60 9D 47 3F 6E 5E 
60 59 34 58 68 41 4B 61 4E 3F 41 46 00

和 ASCII:

UkfQ5YJ\j`@3_EX`G?n^`Y4XhAKaN?AF

这是一个随机生成的字符串,用于测试我的子程序。

char * buffer = [randomNSString UTF8String];
// .... doing things .... in the end, buffer is the same as before
NSString * result = [NSString stringWithUTF8String:buffer];
// yields nil

编辑:以防万一有人没有理解隐含的问题,这里是 -v 模式:

为什么 [NSString stringWithUTF8String:] 有时会在完美格式的 UTF8-String 上返回 nil

【问题讨论】:

  • -UTF8String-stringWithUTF8String: 之间自动释放池是否有可能耗尽?
  • @Bavarious:不,buffer 在调用 stringWithUTF8String: 时仍然活着并且还在踢。
  • 您能发布产生该缓冲区的原始 UTF-8 字符串吗?可能首先通过-dataUsingEncoding: 表示NSData,然后是-UTF8String 之后的缓冲区。
  • 给定的 ASCII 和十六进制表示之间不匹配 - ASCII 中不存在 9D。
  • 查看 UTF8 规范,这个缓冲区是 not 有效的 UTF8,所以 NSString 失败是正确的。所以我想问题是 为什么 不对?如果你去掉中间人,直接去result=[NSString stringWithUTF8String:[randomNSString UTF8String]],你会得到一个有效的结果吗?

标签: objective-c cocoa utf-8 nsstring


【解决方案1】:

walkytalky 是对的。 9d 以这种方式在 utf8 中是不合法的。高位为 10 的 utf8 字节被保留为连续字符,它们永远不会在没有超过一位前导位的前缀字符的情况下出现。

【讨论】:

    【解决方案2】:

    这有点摸不着头脑,因为我们没有足够的信息来正确诊断问题。

    如果randomNSString 在您为result 分配内存时不再存在,例如,如果它已在引用计数环境中释放或在GC 环境中收集,则buffer 可能指向已释放但尚未重用的内存(这可以解释为什么它仍然相同)。

    但是,创建一个新的 NSString 需要分配内存,并且它可能会使用缓冲区指向的块,这意味着您的 UTF8 字符串会被新 NSString 的内部结构破坏。您可以通过在创建result 失败后 登录缓冲区的内容来测试这个理论。但是不要使用 %s 说明符,打印十六进制字节。

    【讨论】:

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