Swift 3.0 Unsafe World
Roberto Perez (via Hacker News):
But, what if we want to take a pointer to a Swift managed memory without having to create a function? To do it we will use
withUnsafeMutablePointer
, that will take a reference to a Swift type and a block with the pointer as it’s parameter.[…]
When dealing with C API you need sometimes to cast pointers to struct to a different struct. This is very easy to do en C (and very dangerous and error prone too), as you have seen in Swift, all pointers are typed, that means that an
UnsafePointer<Int>
cannot be used where anUnsafePointer<UInt8>
is required, that’s good in terms of producing a safer code, but at the same time that makes not possible to interact with C APIs that requires this types of casts, like for example socketbind()
function. For theses cases, we will usewithMemoryRebound
which is a function that will convert a pointer from a type to a different one.[…]
Before Swift 3.0, you could do it with
UnsafePointer<Void>
however, in 3.0 a new type has been added to handle these types of pointers:UnsafeRawPointer
. This struct is not generic, so it means that it won’t hold information tied to any specific type and that will simplifly our code.[…]
If we construct a
UnsafeBufferPointer
from anUnsafePointer
we will be able to use most of the array functions of native Swift type given thatUnsafeBufferPointer
implementsCollection
,Indexable
andRandomAccessCollection
swift protocols.[…]
Swift has an utility to take pointers to objects retaining its reference or not depending on our needs. Those are static functions of
Unmanaged
struct. WithpassRetained()
we will create a retained reference to an object, so we can be sure that when using it from C world, it will be still there. If the object is already retained for the life of the callback we can also usepassUnretained()
. Both methods produces a instance ofUnmanaged
that will be converted to aUnsafeRawPointer
by callingtoOpaque()