Swift: withUnsafePointerToElements
There is no escape, only vectors
Swift Array<T> is easily convertible to a C-style array, but much like the world of Garbage Collection, we have to be aware of object lifetimes.
A Swift Array is just a small stack-allocated header struct that points at heap-allocated memory to hold the elements. When you mutate an array, that header struct may change. If the array is resized, it may need to be moved on the heap. If the array is bridged to Objective-C, the last strong reference may disappear on another thread while your call to the world of C is still happening.
That's where Array's withUnsafePointerToElements
comes in. It takes a single closure, passing you an UnsafePointer
. For the duration of that closure, you can be sure the array is safe to treat as a dumb pointer, just like C.
Let's look at an example:
var buf:Array<CChar> = []
//put some stuff in the buffer
buf += CChar(0) //CRITICAL or you'll overrun the buffer on the next line
let myStr = buf.withUnsafePointerToElements { String.fromCString($0) }
Here we declare a mutable array of CChar, then presumably put some data in that buffer. Then, we terminate it with a NULL, otherwise fromCString
is going to run off the end and everything is fine right up until the crying.
Last we want to call String.fromCString
and pass it the array, but we can't do that directly. Instead, we wrap the call in Array.withUnsafePointerToElements
.
Enjoy!
Next time: Pointers everywhere, or Unsafety? More like FUnsafety.
This blog represents my own personal opinion and is not endorsed by my employer.