0

我有NSData *data。它的价值是000e

因此十进制值为14

现在我想把这个值变成原始NSUInteger的。

我试过了

NSUInteger *hereIWant14 = (NSUInteger *)data.bytes;

*hereIWant14价值是3584e00进制的。现在我不知道字节序或字体大小是否有问题,或者我的想法完全错误000ee00相似性纯属偶然。

4

2 回答 2

2

它与字节顺序有关。使用 Endian.h 中定义的转换宏:

EndianU16_BtoN(value)
EndianU16_NtoB(value)
EndianS32_BtoN(value)
EndianS32_NtoB(value)
EndianU32_BtoN(value)
EndianU32_NtoB(value)
EndianS64_BtoN(value)
EndianS64_NtoB(value)
EndianU64_BtoN(value)
EndianU64_NtoB(value)
etc.

方法签名意味着:

Endian + U 无符号 S 有符号 + 位数 + N是系统的本地字节序,L是小端序,B是大端序

因此,如果您有一个内容为 (0x00, 0xE0) 的 NSData,并且您想将其解释为值 14,那么它包含大端序的数据,因此您必须使用EndianU32_BtoN(当然,这个宏是大端系统上的恒等变换,只在小端机器上交换字节)。

重要提示:为了面向未来,我建议您使用其他东西而不是 NSUInteger,因为这种类型的宽度可能因不同系统而异(例如,Apple 在 arm64 系统上将 NSUInteger 定义为 64 位)。因此,要明确说明位数,请使用 uint32_t 或 uint64_t 等。

编辑:Big-Endian 短值的用法

NSMutableData * data = [[NSMutableData alloc] initWithLength:2];
((unsigned char *)data.mutableBytes)[0] = 0x00;
((unsigned char *)data.mutableBytes)[1] = 0x0E;

NSUInteger integer = NSSwapBigShortToHost(*(unsigned short *)data.mutableBytes);

NSLog(@"%d", integer); // prints 14
于 2013-09-23T13:53:02.847 回答
2

是的,这是因为如上所述的字节序。

如果你需要从 NSData 读取两段代码:

u_int16_t signature;
[data getBytes:&signature           range:NSMakeRange(0, 2)];
signature = CFSwapInt16(signature);

通常我使用 CFSwapInt16 或 CFSwapInt32(用于 u_int32_t)。否则,如果您必须阅读例如字符串:

char charArray[length];
[data getBytes:charArray range:NSMakeRange(0, length)];
NSData* data = [NSData dataWithBytes:charArray length:length];
NSString* string = [[NSString alloc]initWithData:data encoding:NSStringEncodingConversionAllowLossy];

希望它可以帮助!

于 2013-09-23T14:45:38.950 回答