2016-11-02 24 views
5

Tôi có một chút vấn đề với luật của tôi sau khi cập nhật lên Swift 3. Tôi có Bộ luật này trước khi chuyển đổi:Swift: Không thể chuyển đổi giá trị của loại 'UnsafeMutablePointer' để loại lập luận dự kiến ​​'UnsafeMutablePointer'

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

Và tôi chuyển đổi nó để Bộ luật này và trong dòng thứ 3 tôi nhận được một lỗi

... không thể chuyển đổi giá trị của loại 'UnsafeMutablePointer' để loại lập luận dự kiến ​​'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() 
    } 
} 

Có ai biết cách loại bỏ điều này không?

Trả lời

4

copyBytes hy vọng một UnsafeMutableBufferPointer như là đối số: (. allocate() mất số lượng "mặt hàng" như là đối số, không phải là số byte)

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

Nhưng lưu ý rằng phương pháp của bạn bị rò rỉ bộ nhớ, bộ nhớ phân bổ được deinitialized (với move()) nhưng cũng phải là deallocated:

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 
    } 
} 

Một giải pháp đơn giản sẽ là (từ round trip Swift number types to/from Data):

extension Data { 
    func castToCPointer<T>() -> T { 
     return self.withUnsafeBytes { $0.pointee } 
    } 
} 
+0

Cảm ơn bạn :) người cuối cùng làm việc hoàn toàn !! –

0

Bạn cũng có thể sử dụng dưới cú pháp trong phần mở rộng

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) 
} 
Các vấn đề liên quan