【问题标题】:NSData to primitiveNSData 到原始
【发布时间】:2013-09-28 10:45:36
【问题描述】:

我有NSData *data。它的值为000e

因此十进制值为14

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

我试过了

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

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

【问题讨论】:

    标签: ios objective-c c macos


    【解决方案1】:

    这与字节顺序有关。使用 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
    

    【讨论】:

    • 由于 Endian.h 是 CarbonCore 的遗留文件,我使用了 NSSwapBigIntToHost。我想它做同样的事情。在NSUInteger foo = NSSwapBigIntToHost(*hereIWant14); foo 之后是917504 而不是14
    • 这是因为 BigInt 需要 32 位(4 字节)。您应该使用 NSSwapBigShortToHost 2 个字节。 (编辑了我的答案)
    【解决方案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];
    

    希望对你有帮助!

    【讨论】:

      猜你喜欢
      • 2012-08-20
      • 1970-01-01
      • 1970-01-01
      • 2011-03-02
      • 1970-01-01
      • 1970-01-01
      • 2014-11-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多