【问题标题】:NSData from Byte array in SwiftSwift中字节数组的NSData
【发布时间】:2014-06-13 02:32:04
【问题描述】:

我正在尝试从一个字节数组创建一个NSDatavar

在 Obj-C 中我可能会这样做:

NSData *endMarker = [[NSData alloc] initWithBytes:{ 0xFF, 0xD9 }, length: 2]

我无法在 Swift 中找到一个有效的等价物。

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    NSData 有一个初始化器,它接受一个bytes 指针:init(bytes: UnsafeMutablePointer <Void>, length: Int)UnsafePointer 参数可以接受各种不同的东西,包括一个简单的 Swift 数组,因此您可以使用与 Objective-C 中几乎相同的语法。当您传递数组时,您需要确保将其识别为 UInt8 数组,否则 Swift 的类型推断将假定您的意思是创建一个 Int 数组。

    var endMarker = NSData(bytes: [0xFF, 0xD9] as [UInt8], length: 2)
    

    您可以在 Apple 的 Interacting with C APIs 文档中阅读有关不安全指针参数的更多信息。

    【讨论】:

    • 所以我也是这么想的。但是当我在调试器中打印出来时,我得到: ;如果我做更多的字节,我会得到同样的结果,第一个字节之后都是 00。
    • 向数组添加类型信息 - 它发送的是 Int 数组,而不是 Byte 数组。
    • 只是补充,Byte在swift1.2中被删除,改用UInt8
    • 我只是在学习 Swift,所以这可能是一个愚蠢的问题。如果我写以下内容:“_fileHandle!.write(NSData(bytes: UnsafePointer(byteData), length: byteLength) as Data)”那么它可以正常工作。但我担心这可能涉及创建一个 byteData 的新副本,它是一个 100 KB 字节数组。确定不是?
    【解决方案2】:
    var foo : Byte[] = [0xff, 0xD9]
    
    var data = NSData(bytes: foo, length: foo.count)
    
    println("\(data)")
    

    输出:ff d9

    var data = NSData(bytes: [0xFF, 0xD9] as Byte[], length: 2)
    
    println("\(data)")
    

    输出:ff d9

    编辑:啊,你必须写'as Byte[]',所以结果是一样的


    为 Swift 2.2 更新

    var foo:[UInt8] = [0xff, 0xD9]
    var data = NSData(bytes: foo, length: foo.count)
    print("\(data)")
    

    输出:ff d9

    var data = NSData(bytes: [0xFF, 0xD9] as [UInt8], length: 2)
    print("\(data)")
    

    输出:ff d9

    【讨论】:

    • 看起来你不能在 Swift 1.2 中使用 Byte 了。而不是Byte[],写[Uint8]
    • 不是UInt8(拼写)
    【解决方案3】:

    你不需要扩展 Data,在 Swift 3 中你可以这样做:

    let bytes:[UInt8] = [0x00, 0x01, 0x02, 0x03]
    let data = Data(bytes: bytes)
    print(data as NSData)
    

    打印“”

    再次获取字节数组:

    let byteArray:[UInt8] = [UInt8](data)
    

    【讨论】:

    • 谢谢。 Swift 4 有什么变化吗?
    【解决方案4】:

    Swift 3 扩展

    extension Data {
    
        init<T>(fromArray values: [T]) {
            var values = values
            self.init(buffer: UnsafeBufferPointer(start: &values, count: values.count))
        }
    
        func toArray<T>(type: T.Type) -> [T] {
            return self.withUnsafeBytes {
                [T](UnsafeBufferPointer(start: $0, count: self.count/MemoryLayout<T>.stride))
            }
        }
    }
    

    用法

    let bytes:[UInt8] = [0x00, 0xf4, 0x7c]
    let data = Data(fromArray: someBytes)
    print(data as NSData)
    
    let bytes = data.toArray(type: UInt8.self)
    print(bytes)
    

    【讨论】:

      【解决方案5】:

      对于 Swift 5,我创建了另一个运行良好的 Data 扩展。

      extension Data {
      
          init<T>(fromArray values: [T]) {
              var values = values
              self.init(buffer: UnsafeBufferPointer(start: &values, count: values.count))
          }
      
          func toArray<T>(type: T.Type) -> [T] {
              let value = self.withUnsafeBytes {
                  $0.baseAddress?.assumingMemoryBound(to: T.self)
              }
              return [T](UnsafeBufferPointer(start: value, count: self.count / MemoryLayout<T>.stride))
          }
      
      }
      

      示例用法

      let data = Data(fromArray: [1, 2, 3, 4, 5])
      let array = data.toArray(type: Int.self)
      print(array)
      // [1, 2, 3, 4, 5]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-28
        • 1970-01-01
        • 2011-12-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多