如何将 NSData 转换为多种类型的 Int [英] How to convert NSData to multiple type Ints

查看:116
本文介绍了如何将 NSData 转换为多种类型的 Int的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过 get NSData() 获取磁力计调整寄存器,如下所示:

I obtain magnetometer trim register as get NSData() that looks as follows:

<00001a1a 4f56f202 00000000 1dfd421b>

我需要根据我访问的字节将其转换为 Int8、UInt8、Int16、UInt16.

I need to convert it to Int8, UInt8, Int16, UInt16 depending on which byte I access.

来自文档的来源:

s8 dig_x1;/**< trim x1 data */
s8 dig_y1;/**< trim y1 data */

s8 dig_x2;/**< trim x2 data */
s8 dig_y2;/**< trim y2 data */

u16 dig_z1;/**< trim z1 data */
s16 dig_z2;/**< trim z2 data */
s16 dig_z3;/**< trim z3 data */
s16 dig_z4;/**< trim z4 data */

u8 dig_xy1;/**< trim xy1 data */
s8 dig_xy2;/**< trim xy2 data */

u16 dig_xyz1;/**< trim xyz1 data *

主要问题是如何访问 NSData 中选定的字节以将其手动转换为 Int8 或 UIint16 等?

The main problem is how to access a selected byte in NSData to convert it manually either to Int8 or UIint16 etc?

一般来说,如何处理这样的问题?是否应该寻找一种方法来手动迭代 NSData 并手动转换每个值?

Generally, how to approach such problem? Should look for a way to manually iterate over NSData and convert each value manualy as well?

推荐答案

您可以将 data.bytes + offset 转换为适当的类型,然后取消引用指针:

You can convert data.bytes + offset to a pointer of the appropriate type and then dereference the pointer:

let dig_x1 = UnsafePointer<Int8>(data.bytes).memory
let dig_y1 = UnsafePointer<Int8>(data.bytes + 1).memory
// ...
let dig_z1 = UnsafePointer<UInt16>(data.bytes + 4).memory
let dig_z2 = UnsafePointer<Int16>(data.bytes + 6).memory
// ...

(注意:这里假设二进制 blob 中的所有值都是属性与其类型对齐.)

数据是little-endian字节顺序,这也是所有当前iOS平台使用.为了安全起见,转换显式托管字节顺序的数据:

The data is in little-endian byte order, which is also what all current iOS platforms use. To be on the safe side, convert the data to host byte order explicitly:

let dig_z1 = UInt16(littleEndian: UnsafePointer(data.bytes + 4).memory)
let dig_z2 = Int16(littleEndian: UnsafePointer(data.bytes + 6).memory)
// ...

另一种方法是在桥接头文件中定义一个 C 结构

An alternative is to define a C structure in the bridging header file

struct MagnetometerData {
    int8_t dig_x1;
    int8_t dig_y1;

    int8_t dig_x2;
    int8_t dig_y2;

    uint16_t dig_z1;
    int16_t dig_z2;
    int16_t dig_z3;
    int16_t dig_z4;

    uint8_t dig_xy1;
    int8_t dig_xy2;

    uint16_t dig_xyz1;
} ;

并一步提取数据:

var mdata = MagnetometerData()
data.getBytes(&mdata, length: sizeofValue(mdata))

这有效(如果结构成员之间没有填充)因为 Swift 保留从 C 导入的结构的布局.

This works (if there is no padding between the struct members) because Swift preserves the layout of structures imported from C.

第一种方法的一种可能的 Swift 3 实现是

A possible Swift 3 implementation of the first approach is

let dig_x1 = ((data as NSData).bytes).load(as: Int8.self) 
let dig_y1 = ((data as NSData).bytes + 1).load(as: Int8.self)
// ...
let dig_z1 = ((data as NSData).bytes + 4).load(as: UInt16.self) 
let dig_z2 = ((data as NSData).bytes + 6).load(as: Int16.self) 
// ...

再次假设所有的值都是针对它们的属性对齐的类型.

Again it is assumed that all values are property aligned for their type.

这篇关于如何将 NSData 转换为多种类型的 Int的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆