gpt4 book ai didi

ios - 在 Swift 中从 NSData 读取时的 EXC_ARM_DA_ALIGN

转载 作者:行者123 更新时间:2023-11-28 07:10:58 24 4
gpt4 key购买 nike

我有以下类(class):

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 Air 模拟器中运行,并且已经通过了 Beta 测试的审查。但是,我的外部测试人员使用的是 iPad 2s 和 4s,他们遇到了 EXC_ARM_DA_ALIGN 错误。

我无法更改输入文件的结构。有什么方法可以修复 read 函数以确保对象是从正确对齐的内存位置构建的?

最佳答案

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

所以第一个想法是编写一个通用函数:

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
}

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

对于一般情况,可以使用 https://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 允许重载具有不同返回类型的函数,因此你实际上可以定义两个方法,编译器会自动选择限制性更强的一个。

关于ios - 在 Swift 中从 NSData 读取时的 EXC_ARM_DA_ALIGN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28507412/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com