Reputation: 1209
I have a little Problem with my Code after updating to Swift 3. I had this Code before the conversion:
extension NSData {
func castToCPointer<T>() -> T {
let mem = UnsafeMutablePointer<T>.alloc(sizeof(T.Type))
self.getBytes(mem, length: sizeof(T.Type))
return mem.move()
}
}
And I converted it to this Code and in the 3rd line I get an Error
... Cannot convert value of type 'UnsafeMutablePointer' to expected argument type '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()
}
}
Does anyone know how to get rid of this?
Upvotes: 10
Views: 28180
Reputation: 540065
copyBytes
expects a UnsafeMutableBufferPointer
as argument:
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()
takes the number of "items" as argument, not the number of
bytes.)
But note that your method leaks memory, the allocated memory
is deinitialized (with move()
) but also has to be
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()
return val
}
}
Upvotes: 8
Reputation: 4749
You can also use below syntax in extension
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)
}
Upvotes: -1