10

更新到 Swift 3 后,我的代码有点问题。在转换之前我有这个代码:

extension NSData {
  func castToCPointer<T>() -> T {
    let mem = UnsafeMutablePointer<T>.alloc(sizeof(T.Type))
    self.getBytes(mem, length: sizeof(T.Type))
    return mem.move()
  }
}

我把它转换成这个代码,在第三行我得到一个错误

...无法将“UnsafeMutablePointer”类型的值转换为预期的参数类型“UnsafeMutablePointer”

extension Data {
  func castToCPointer<T>() -> T{
    let mem = UnsafeMutablePointer<T>.allocate(capacity: MemoryLayout<T.Type>.size)
    self.copyBytes(to: mem, count: MemoryLayout<T.Type>.size)
    //self.copyBytes(to: mem, count: MemoryLayout<T.Type>.size)
    return mem.move()
  }
}

有谁知道如何摆脱这个?

4

2 回答 2

8

copyBytes期望一个UnsafeMutableBufferPointeras 参数:

extension Data {
    func castToCPointer<T>() -> T {
        let mem = UnsafeMutablePointer<T>.allocate(capacity: 1)
        _ = self.copyBytes(to: UnsafeMutableBufferPointer(start: mem, count: 1))
        return mem.move()
    }
}

allocate()将“项目”的数量作为参数,而不是字节数。)

但请注意,您的方法会泄漏内存,分配的内存被取消初始化(使用move())但也必须被释放:

extension Data {
    func castToCPointer<T>() -> T {
        let mem = UnsafeMutablePointer<T>.allocate(capacity: 1)
        _ = self.copyBytes(to: UnsafeMutableBufferPointer(start: mem, count: 1))
        let val =  mem.move()
        mem.deallocate(capacity: 1)
        return val
    }
}

一个更简单的解决方案是(从 往返 Swift 数字类型到/从 Data):

extension Data {
    func castToCPointer<T>() -> T {
        return self.withUnsafeBytes { $0.pointee }
    }
}
于 2016-11-02T10:44:56.403 回答
-1

您还可以在扩展中使用以下语法

extension Data {
    func castToCPointer<T>() -> T {
        var bytes = self.bytes
        var val = withUnsafePointer(to: &bytes) { (temp) in
            return unsafeBitCast(temp, to: T.self)
        }
        return val
    }
}

var data:NSData/NSMutableData
var bytes = data.bytes
var val = withUnsafePointer(to: &bytes) { (temp) in
   return unsafeBitCast(temp, to: T.self)
}
于 2016-11-02T18:19:14.067 回答