swift - 在Swift中,EXC_ARM_DA_ALIGN读取NSData时

  显示原文与译文双语对照的内容
0 0

我有以下类:


class RawDataArray {
 var data: NSData!

 init(filePath: String) {
 data = NSData(contentsOfFile: filePath)
 }

 func read<T>(offset: Int) -> T {
 return UnsafePointer<T>(data.bytes + offset).memory
 }
}

在iOS应用程序中使用,以使用自定义格式从二进制文件读取。 例如若要读取偏移量 5处的Int,请使用:

let foo = rawData.read(5) as Int

这在我的iPad空气模拟器上工作,并且已经通过了测试测试。 但是,我的外部测试人员有 iPad 2s 和 4 s,而且他们正在获得 EXC_ARM_DA_ALIGN 错误。

我无法更改输入文件的结构。 是否有办法修复 read 函数以确保这些对象是由正确对齐的内存位置构建的?

时间: 原作者:

0 0

是,在某些架构中读取未对齐的数据可能会失败。 一种安全方法是将字节复制到( 正确对齐) 变量。

因此,第一个想法是编写一个通用函数:


func read<T>(offset: Int) -> T {
 var value : T
 memcpy(&value, data.bytes + offset, UInt(sizeof(T)))
 return value
}

然而,这个函数不能编译,因为变量 value 必须在使用之前初始化,并且没有默认的构造函数可以用来初始化完整的泛型变量。

如果将方法限制为可以使用 0 初始化的类型,则得到以下结果:


func read<T : IntegerLiteralConvertible>(offset: Int) -> T {
 var value : T = 0
 memcpy(&value, data.bytes + offset, UInt(sizeof(T)))
 return value
}

这适用于所有整数和浮点类型。

对于一般情况,可以使用 http://stackoverflow.com/a/24335355/1187415 中的概念:


func read<T>(offset: Int) -> T {
//Allocate space:
 let ptr = UnsafeMutablePointer<T>.alloc(1)
//Copy data:
 memcpy(ptr, data.bytes + offset, UInt(sizeof(T)))
//Retrieve the value as a new variable: 
 var item = ptr.move()
//Free the allocated space
 ptr.dealloc(1)
 return item
}

Swift允许重载不同返回类型的函数,因此你可以实际定义方法,编译器将自动选择限制性更强的函数。

原作者:
...