如何将 NSData 转换为多种类型的 Ints
How to convert NSData to multiple type Ints
我获得磁力计 trim 注册为 get NSData() ,如下所示:
<00001a1a 4f56f202 00000000 1dfd421b>
我需要根据访问的字节将其转换为 Int8、UInt8、Int16、UInt16。
来自文档的来源:
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 等?
一般情况下,如何处理这样的问题?是否应该寻找一种方法来手动迭代 NSData 并手动转换每个值?
您可以将 data.bytes + offset
转换为
适当的类型,然后取消引用指针:
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 中的所有值都是
属性 与其类型对齐。)
数据是小端字节序,也是什么
当前 iOS 平台使用。为了安全起见,转换
主机字节顺序的数据明确:
let dig_z1 = UInt16(littleEndian: UnsafePointer(data.bytes + 4).memory)
let dig_z2 = Int16(littleEndian: UnsafePointer(data.bytes + 6).memory)
// ...
另一种方法是在桥接头文件中定义一个 C 结构
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 导入的结构布局
第一种方法的可能Swift3实现是
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)
// ...
再次假定所有值都属性与其对应
类型。
我获得磁力计 trim 注册为 get NSData() ,如下所示:
<00001a1a 4f56f202 00000000 1dfd421b>
我需要根据访问的字节将其转换为 Int8、UInt8、Int16、UInt16。
来自文档的来源:
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 等?
一般情况下,如何处理这样的问题?是否应该寻找一种方法来手动迭代 NSData 并手动转换每个值?
您可以将 data.bytes + offset
转换为
适当的类型,然后取消引用指针:
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 中的所有值都是 属性 与其类型对齐。)
数据是小端字节序,也是什么 当前 iOS 平台使用。为了安全起见,转换 主机字节顺序的数据明确:
let dig_z1 = UInt16(littleEndian: UnsafePointer(data.bytes + 4).memory)
let dig_z2 = Int16(littleEndian: UnsafePointer(data.bytes + 6).memory)
// ...
另一种方法是在桥接头文件中定义一个 C 结构
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 导入的结构布局
第一种方法的可能Swift3实现是
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)
// ...
再次假定所有值都属性与其对应 类型。