【发布时间】:2016-05-31 04:51:09
【问题描述】:
我的应用程序通过persistentId 记住MPMediaItems,就像一个人一样。它将 persistentId 保存在 JSON 文件中,稍后读取和解析该文件。 NSJSONSerialization 创建一个 NSDecimalNumber 来包含 Id,我的应用稍后在 MPMediaQuery 中使用它来获取 MPMediaItem。
我发现有时会发现错误的 MPMediaItem。当我再四处寻找时,我发现当我将 NSDecimalNumber 转换为 uint64_t 值时,[NSNumber unsignedLongLongValue] 返回了错误的值!
NSDecimalNumber* const songId = _songId;
uint64_t const songIdValue = songId.unsignedLongLongValue;
songId is 1457249251113381177
songIdValue is 1457249251113381120
-or-
songId is 0x1439307919d12d39
songIdValue is 0x1439307919d12d00
什么鬼?看起来低字节在将此 NSDecimalNumber 转换为 uint64_t 时被清除。这是 NSDecimalNumber 的某种正确行为吗?我发现其中有错误吗?
我正在通过将 NSDecimalNumber 从 NSJSONSerialization 转换为字符串并使用 [NSString longLongValue] 将字符串转换为 uint64_t 来解决此问题。
这很可怕,因为我现在似乎必须检查我在 JSON 文件中存储大整数的每个地方,并确保我以这种 NSString-y 方式评估它们。
【问题讨论】:
-
我在这里找到了一条评论,说 NSDecimalNumber 在转换为 uint64_t 之前先转换为双精度数。因此,任何超过 53 的有效位都会被清除,正如我在这里看到的那样。令人难以置信的是,Apple 让这一切站稳了脚跟! NSJsonSerialization 在为整数而不是 NSNumber 选择此类时出错。我打算将我的 JSON 解析切换到 JSONKit,我建议其他人也这样做。
-
在他的评论中,Christopher 可能指的是this answer to NSDecimalNumber and large unsigned long long (64-bit) integers
标签: ios cocoa nsdecimalnumber