简体   繁体   English

Swift 数据到 Int 数组

[英]Swift Data to Int array

I'd like to access the raw bytes in Data as an array of numeric types for quick parsing.我想访问 Data 中的原始字节作为数字类型的数组以进行快速解析。 I have lots of data to parse, so I'm looking for efficiency.我有很多数据要解析,所以我正在寻找效率。 Data is a mix of shorts, ints, longs, and doubles.数据是短裤、整数、长裤和双打的混合。

The below code seems to work and be fast, but I'm getting deprecated warning: 'withUnsafeBytes' is deprecated下面的代码似乎可以工作并且速度很快,但是我收到了弃用警告:'withUnsafeBytes' is deprecated

I can't figure out the updated way to treat the underlying bytes as an array of numbers for quick lookup.我想不出将底层字节视为数字数组以进行快速查找的更新方法。

    var data: Data = ...
            
    // create "virtual" arrays of different types to directly access bytes (without copying bytes)
    
    let ushortArray: [UInt16] = data.withUnsafeBytes {
        [UInt16](UnsafeBufferPointer(start: $0, count: data.count/2))
    }
    let intArray: [Int32] = data.withUnsafeBytes {
        [Int32](UnsafeBufferPointer(start: $0, count: data.count/4))
    }

    // Access data simply
    var i1: UInt16 = ushortArray[0]
    var i2: Int32 = intArray[1]

PS I'm not concerned with big/little endian PS 我不关心大/小端

If you want to load it as an Array what you need is to use UnsafeRawBufferPointer bindMemory method to the type you want.如果你想将它作为一个数组加载,你需要的是将UnsafeRawBufferPointer bindMemory方法用于你想要的类型。 you can also extend ContiguousBytes to make a generic method and simplify your syntax:您还可以扩展 ContiguousBytes 以创建通用方法并简化语法:

Note: if you are planing to get a subsequence of your data make sure to do NOT subscript the data to avoid misaligned errors.注意:如果您打算获取数据的子序列,请确保不要下标数据以避免未对齐的错误。 You need to use Data subdata method instead.您需要改用数据子数据方法。

extension ContiguousBytes {
    func objects<T>() -> [T] { withUnsafeBytes { .init($0.bindMemory(to: T.self)) } }
    var uInt16Array: [UInt16] { objects() }
    var int32Array: [Int32] { objects() }
}

extension Array {
    var data: Data { withUnsafeBytes { .init($0) } }
}

Usage:用法:

let uInt16Array: [UInt16] = [.min, 1, 2, 3, .max]  // [0, 1, 2, 3, 65535]
let int32Array: [Int32] = [.min, 1, 2, 3, .max]    // [-2147483648, 1, 2, 3, 2147483647]

let uInt16ArrayData = uInt16Array.data  // 10 bytes
let int32ArrayData = int32Array.data    // 20 bytes

let uInt16ArrayLoaded = uInt16ArrayData.uInt16Array  // [0, 1, 2, 3, 65535]
let int32ArrayLoaded = int32ArrayData.int32Array       // [-2147483648, 1, 2, 3, 2147483647]

// Access data simply
let i1 = uInt16ArrayLoaded[0]   //  UInt16 0
let i2 = int32ArrayLoaded[0]    // Int32 -2147483648
let i3 = uInt16ArrayLoaded[4]   //  UInt16 65535
let i4 = int32ArrayLoaded[4]    // Int32 2147483647

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM