3

当我尝试使用大于 -2 且小于 13 的数字的 numberWithLongLong 创建 NSNumber 时,它会返回一个转换为 (int) 的数字。

如果我在跨过我的线路后查看 Xcode 调试器,我会看到这一点。

NSNumber* numberA = [NSNumber numberWithLongLong:-2]; //Debugger shows as (long)-2
NSNumber* numberB = [NSNumber numberWithLongLong:-1]; //Debugger shows as (int)-1
NSNumber* numberC = [NSNumber numberWithLongLong:12]; //Debugger shows as (int)12
NSNumber* numberD = [NSNumber numberWithLongLong:13]; //Debugger shows as (long)13

为了把我的问题放在上下文中,我使用一个 long long 值作为一个纪元日期,我最终将使用 BSON 序列化并通过线路发送到 Web 服务。Web 服务要求日期为 java Long。

提前致谢

4

3 回答 3

6

您已经发现 NSNumber(实际上,它的 CFNumber 对应物)有一个用于 -1 到 12 之间的整数的缓存。看一下CFNumberCreate函数,CFNumber.c看看它是如何工作的。

看起来您可以通过将自己的分配器传递给CFNumberCreate. 您需要查看CFAllocator文档。

但请注意,CFNumberCreate手册是这样说的:

创建新对象theType时,不一定要保留该参数。CFNumber

因此,即使您绕过缓存,您也可能无法取回objCTypeis q(这意味着long long)的对象。看起来当前的实现将返回q,但在未来的版本中可能会改变。

NSNumber如果您需要保证objCType返回,您可以编写自己的子类q。阅读NSNumber 类参考中的“子类化注释”

于 2013-04-13T01:41:57.757 回答
3

您可以毫无顾虑地使用您的网络服务。

NSNumber将数值(原始类型)包装为对象。如何NSNumber存储该值并不是您真正关心的问题(但有一种方法可以找到它),它是一种不透明的类型。然而NSNumber,它确实维护了用于创建它的类型的内部记录,因此它的compare:方法可以遵循 C 规则来精确地比较不同类型的值。

对于整数类型,在数学意义上,您返回的整数值将与您创建的整数值完全相同NSNumberNSNumber您可以使用 a创建一个short并将其值读回为 a long long,即使表示不同,数学值也将相同。

因此,您可以将积分日期值存储为 an NSNumber,当您将其读取为 a 时,long long您将获得正确的值。无需担心如何NSNumber在内部表示它,实际上这可能会在未来发生变化。

(至少有一种实现NSNumber可以将值存储为 128 位整数,这有助于确保有符号和无符号整数的正确语义。我还强调了整数类型,就像实数的变幻莫测一样,谈论数学精确性有点没有实际意义。)

于 2013-04-13T03:06:02.317 回答
1

等待。我想我知道你在问什么。试试这种方式:

NSNumber* numberA = [NSNumber numberWithLongLong:-2LL];
NSNumber* numberB = [NSNumber numberWithLongLong:-1LL];
NSNumber* numberC = [NSNumber numberWithLongLong:12LL];
NSNumber* numberD = [NSNumber numberWithLongLong:13LL];

顺便说一句:常量的类型是什么无关紧要,它会long long在传递给时被强制转换为[NSNumber numberWithLongLong:]


更新

根据@robmayoff 的回答,我认为 NSNumber 对您来说并不可靠。你是如何包装你的 BSON 的?有没有办法使用 NSValue 而不是 NSNumber?

于 2013-04-13T01:17:08.423 回答