【问题标题】:EXC_ARM_DA_ALIGN when reading from NSData in Swift在 Swift 中从 NSData 读取时的 EXC_ARM_DA_ALIGN
【发布时间】:2015-02-13 19:37:16
【问题描述】:

我有以下课程:

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 函数以确保对象是从正确对齐的内存位置构建的?

【问题讨论】:

    标签: ios swift unsafe-pointers


    【解决方案1】:

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

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

    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 允许重载具有不同返回类型的函数, 因此,您实际上可以定义 both 方法,编译器将 自动选择更严格的那个。

    【讨论】:

    • 非常感谢您拯救了我的周末!我正要开始编写一些糟糕的代码来转移字节等。
    【解决方案2】:

    致所有SWIFT阅读本文的开发人员

    我有一个不同的案例,同样的崩溃类型!

    如果您的项目是为(旧的?)swift 版本定义的,但您在 构建设置 中链接到具有不同(较新?)swift 版本的可可豆荚(在我的情况下) - 您'即使您只是尝试在常规 swift struct 中设置公共字段的值,也会发生 crash

    堆栈跟踪不会告诉您任何信息,并且可能会显示错误的位置(例如 CAAnimation 空闲内存)

    就我而言,我的项目在 Swift 4 中,而我的 pod (SwiftMessages) 是 Swift 4.2

    并且轰隆隆!!!

    编码愉快!

    【讨论】:

    • 我真的不明白为什么在这里投了 2 票。这个答案对我有帮助,也可能对其他人有帮助..如果答案有任何问题-请发表评论并解释..我不会删除它,因为它将来也可能对我自己有帮助..如果它没有帮助你它没有这并不意味着你需要投反对票
    猜你喜欢
    • 2014-09-29
    • 1970-01-01
    • 2014-07-25
    • 1970-01-01
    • 2016-11-12
    • 2014-12-07
    • 1970-01-01
    • 2016-07-04
    相关资源
    最近更新 更多