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.
The 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 memory property.
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.