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 usewithMemoryReboundwhich 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
UnsafeBufferPointerfrom anUnsafePointerwe will be able to use most of the array functions of native Swift type given thatUnsafeBufferPointerimplementsCollection,IndexableandRandomAccessCollectionswift protocols.[…]
Swift has an utility to take pointers to objects retaining its reference or not depending on our needs. Those are static functions of
Unmanagedstruct. 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 ofUnmanagedthat will be converted to aUnsafeRawPointerby callingtoOpaque()