我有NSData *data
。它的价值是000e
。
因此十进制值为14
。
现在我想把这个值变成原始NSUInteger
的。
我试过了
NSUInteger *hereIWant14 = (NSUInteger *)data.bytes;
但*hereIWant14
价值是3584
六e00
进制的。现在我不知道字节序或字体大小是否有问题,或者我的想法完全错误000e
,e00
相似性纯属偶然。
我有NSData *data
。它的价值是000e
。
因此十进制值为14
。
现在我想把这个值变成原始NSUInteger
的。
我试过了
NSUInteger *hereIWant14 = (NSUInteger *)data.bytes;
但*hereIWant14
价值是3584
六e00
进制的。现在我不知道字节序或字体大小是否有问题,或者我的想法完全错误000e
,e00
相似性纯属偶然。
它与字节顺序有关。使用 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
是的,这是因为如上所述的字节序。
如果你需要从 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];
希望它可以帮助!