Swift: Pointers everywhere
Unsafety? More like FUnsafety
Edit: Updated with new information to clarify that
UnsafePointer<T> expects the number of instances of
T, not the size in bytes.
Today let's discuss
UnsafePointer<T>. Perhaps you want to use a fancy function like
OSAtomicIncrement32 to keep a running counter across threads and GCD queues, without any locking, blocking, or race conditions. How can we accomplish that in Swift?
var count = UnsafePointer<Int32>.alloc(1) count.initialize(0) //do this wherever needed OSAtomicIncrement32(count) //read the result println("\(count.memory)") //don't forget to free count.dealloc(1)
First, we declare an unsafe pointer to an
Int32 and tell Swift how many of that type we want to allocate. Edit: I previously thought the param was the byte size, but John McCall clued me in that Swift is smart enough to know the size of
T, and just wants to know how many of those you'd like.
Next we can't forget to initialize the value to zero, otherwise our count may start with some garbage value (or it may not!), leading to unpredictable behavior.
memory property is how we access the underlying type, assuming Swift understands that type. In the case of
Int32, it does so we're good to go. The type of
memory is determined by the generic type parameter we specified on the previous line.
Now we've got a fancy
UnsafePointer<Int32> and can call the
OSAtomicIncrement32 function. Again, we can access the current value from the
Last but not least, we must
dealloc the memory. Edit: Pass the number of items that were originally allocated. This is an optimization, rather than having to lookup the size from the allocator on every dealloc. Passing a different number from what you passed in
alloc is undefined behavior.
Now go forth and point with ease!
Part 1 Swift: Manual retain/release
Part 2 Swift: withUnsafePointerToElements
This blog represents my own personal opinion and is not endorsed by my employer.