当我尝试使用numberWithLongLong与大于-2且小于13的数字创建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
为了把我的问题放在上下文中,我使用了一个很长的epoch日期值,我最终将使用BSON进行序列化并通过网络发送到web服务。webservice要求日期为java Long。
Thanks in advance
你已经发现NSNumber(实际上,它的CFNumber对应)有一个缓存-1到12之间的整数。看看CFNumber.c
中的CFNumberCreate
函数,看看它是如何工作的。
看起来您可以通过将自己的分配器传递给CFNumberCreate
来强制它不使用缓存。您需要查看CFAllocator
文档。
但请注意CFNumberCreate
手册是这样说的:
创建新的
CFNumber
对象时,不需要保留theType
参数。
因此,即使您绕过缓存,您也可能无法返回objCType
为q
(即long long
)的对象。看起来当前的实现将返回q
,但在未来的版本中可能会改变。
如果你需要保证objCType
返回q
,你可以编写自己的NSNumber
子类。阅读NSNumber类参考中的"子类注释"。
你可以放心使用你的webservice
NSNumber
将数值(基本类型)包装为对象。NSNumber
如何存储该值并不是您真正关心的(但是有一种方法可以找到它),它是一个不透明的类型。然而,NSNumber
确实维护了一个用于创建它的类型的内部记录,因此它的compare:
方法可以精确地遵循C规则来比较不同类型的值。
对于整型,您返回的整型值将在数学意义上与您创建NSNumber
的值完全相同。您可以用short
创建NSNumber
,并将其值读取为long long
,即使表示方式不同,数学值也将相同。
所以你可以将整型日期值存储为NSNumber
,当你将其读取为long long
时,你将得到正确的值。没有必要关心NSNumber
如何在内部表示它,事实上,未来可能会发生变化。
(至少有一种NSNumber
实现可以将值存储为128位整数,这有助于确保有符号和无符号整数的正确语义。我还强调了整型,因为对于变幻莫测的实数,谈论数学的准确性有些意义。
等待。我想我知道你在问什么。试试这样:
NSNumber* numberA = [NSNumber numberWithLongLong:-2LL];
NSNumber* numberB = [NSNumber numberWithLongLong:-1LL];
NSNumber* numberC = [NSNumber numberWithLongLong:12LL];
NSNumber* numberD = [NSNumber numberWithLongLong:13LL];
BTW:无论常量的类型是什么,当传递给[NSNumber numberWithLongLong:]
时,它将被强制转换为long long
根据@robmayoff的回答,我不认为NSNumber对你是可靠的。你是怎么包装你的BSON的?有没有办法用NSValue代替NSNumber?