Swift 2 - UnsafeMutablePointerVoid to object
This should work: pass the object pointer as an opaque unmanaged pointer
to the callback:
context.info = UnsafeMutablePointer(Unmanaged.passUnretained(myObject).toOpaque())
SCNetworkReachabilitySetCallback(reachability, callback, &context)
and retrieve in the callback via:
func callback(reachability:SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutablePointer<Void>) {
let myObject = Unmanaged<MyObject>.fromOpaque(COpaquePointer(info)).takeUnretainedValue()
}
Of course this assumes that some strong reference to the object exists
as long as the callback is installed, so that the object is not
deallocated.
Update: Note that both conversions from object pointer to void pointer
and back can be simplified if you are willing to use "unsafe" functions:
context.info = unsafeAddressOf(myObject)
// ...
myObject = unsafeBitCast(info, MyObject.self)
The generated assembly code is – as far as I can see – identical.
Update 2: See also How to cast self to UnsafeMutablePointer<Void> type in swift for more information
about the "bridging" and some helper functions which can be used here.
Swift 3 update (Xcode 8 beta 6):
var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
context.info = UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque())
// ...
func callback(reachability:SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutableRawPointer?) {
if let info = info {
let myObject = Unmanaged<MyObject>.fromOpaque(info).takeUnretainedValue()
// ...
}
}
UnsafeMutablePointerVoid to [NSObject : AnyObject]
If you want to read trackerData
from the event, you have to get the user info from the tracking area
if let userInfo = theEvent.trackingArea?.userInfo {
let trackerData = userInfo["myTrackerKey"]! as! NSView
// do something with the view
}
UnsafeMutablePointerVoid to Concrete Object Type
UnsafeMutablePointer
has an initializer that takes another UnsafeMutablePointer
of another type, the result being the same pointer but to the new type.
So in your case:
let infoPtr = UnsafeMutablePointer<Info>(context)
let info = infoPtr.memory
Beware though this is, as the docs describe it, "a fundamentally unsafe conversion". If the pointer you have is not a pointer to the type you convert it to, or if the memory you are now accessing it is not valid in this context, you may end up accessing invalid memory and your program will get a little crashy.
Swift casting unsafemutablepointerMyStruct to C void return pointer in swift
look at this 'self explanatory' example
struct MyStruct {
var myId: Int
var myDouble: Double
}
var myStruct = MyStruct(myId: 1, myDouble: 1.0)
// this mimics the funcion which returns Void *myStruct
var vptr = withUnsafeMutablePointer(&myStruct) { (pStruct) -> UnsafeMutablePointer<Void> in
return UnsafeMutablePointer<Void>(pStruct)
}
print(vptr) // 0x00000001079c7828
// mimics mPtr = (MyStruct *) vptr
let mPtr = UnsafeMutablePointer<MyStruct>(vptr) // UnsafeMutablePointer(0x10EE37838)
mPtr.memory.myId = 10
mPtr.memory.myDouble = 10.0
print(myStruct) // MyStruct(myId: 10, myDouble: 10.0)
How to cast self to UnsafeMutablePointerVoid type in swift
An object pointer (i.e. an instance of a reference type) can be
converted to a UnsafePointer<Void>
(the Swift mapping of const void *
, UnsafeRawPointer
in Swift 3) and back. In Objective-C you would write
void *voidPtr = (__bridge void*)self;
//
MyType *mySelf = (__bridge MyType *)voidPtr;
(See 3.2.4 Bridged casts in the Clang ARC documentation for the precise meaning of these
casts.)
Swift has an Unmanaged
type for that purpose.
It is a bit cumbersome to use because it works with COpaquePointer
instead of UnsafePointer<Void>
. Here are two helper methods
(named after the Objective-C __bridge
cast):
func bridge<T : AnyObject>(obj : T) -> UnsafePointer<Void> {
return UnsafePointer(Unmanaged.passUnretained(obj).toOpaque())
// return unsafeAddressOf(obj) // ***
}
func bridge<T : AnyObject>(ptr : UnsafePointer<Void>) -> T {
return Unmanaged<T>.fromOpaque(COpaquePointer(ptr)).takeUnretainedValue()
// return unsafeBitCast(ptr, T.self) // ***
}
The "complicated" expression is only necessary to satisfy Swifts
strict type system. In the compiled code this is just a cast
between pointers. (It can be written shorter as indicated in the ***
comments
if you are willing to use "unsafe" methods, but the compiled
code is identical.)
Using this helper methods you can pass self
to a C function as
let voidPtr = bridge(self)
(or UnsafeMutablePointer<Void>(bridge(self))
if the C function requires
a mutable pointer), and convert it back to an object pointer – e.g.
in a callback function – as
let mySelf : MyType = bridge(voidPtr)
No transfer of ownership takes place, so you must ensure that self
exists as long as the void pointer is used.
And for the sake of completeness, the Swift equivalent of __bridge_retained
and __bridge_transfer
from Objective-C would be
func bridgeRetained<T : AnyObject>(obj : T) -> UnsafePointer<Void> {
return UnsafePointer(Unmanaged.passRetained(obj).toOpaque())
}
func bridgeTransfer<T : AnyObject>(ptr : UnsafePointer<Void>) -> T {
return Unmanaged<T>.fromOpaque(COpaquePointer(ptr)).takeRetainedValue()
}
bridgeRetained()
casts the object pointer to a void pointer and
retains the object. bridgeTransfer()
converts the
void pointer back to an object pointer and consumes the retain.
An advantage is that the object cannot be deallocated between the
calls because a strong reference is held. The disadvantage is that
the calls must be properly balanced, and that it can easily cause retain
cycles.
Update for Swift 3 (Xcode 8):
func bridge<T : AnyObject>(obj : T) -> UnsafeRawPointer {
return UnsafeRawPointer(Unmanaged.passUnretained(obj).toOpaque())
}
func bridge<T : AnyObject>(ptr : UnsafeRawPointer) -> T {
return Unmanaged<T>.fromOpaque(ptr).takeUnretainedValue()
}
func bridgeRetained<T : AnyObject>(obj : T) -> UnsafeRawPointer {
return UnsafeRawPointer(Unmanaged.passRetained(obj).toOpaque())
}
func bridgeTransfer<T : AnyObject>(ptr : UnsafeRawPointer) -> T {
return Unmanaged<T>.fromOpaque(ptr).takeRetainedValue()
}
The relevant changes to "unsafe pointers" are described in
- SE-0017 Change Unmanaged to use UnsafePointer
- SE-0107 UnsafeRawPointer API
Typecast UnsafeMutablePointerVoid to UnsafeMutablePointer#Struct type#
I think what you want to say is something like this:
imageData = UnsafeMutablePointer<PixelRGB>.alloc(dataLength)
New @convention(c) in Swift 2: How can I use it?
You no longer need to create a CFunctionPointer in Swift 2. Instead, you can annotate your type by calling convention, in this case c
, and use it directly.
typealias CFunction = @convention(c) (UnsafeMutablePointer<Void>, Float) -> Int
let bar = unsafeBitCast(foo, CFunction.self)
The relevant bits of the @convention
description in the Type Attributes section of The Swift Programming Language are:
The c argument is used to indicate a C function reference. The function value carries no context and uses the C calling convention.
How do you convert a UnsafeMutablePointerVoid to UInt8?
You have to convert the pointer to the correct type first
(a pointer to UInt8
) and then you can access the memory it points to:
let u8 = UnsafePointer<UInt8>(theUnsafeMutablePointerVar).memory
In Swift 3, a void pointer from C is imported to Swift as UnsafeMutableRawPointer
, and one can read the pointed-to data
with
let u8 = theUnsafeMutablePointerVar.load(as: UInt8.self)
Cannot invoke initializer for type 'UnsafeMutablePointer'
Check the type of info
property from the latest reference:
Declaration
var info: UnsafeMutableRawPointer?
And the type of toOpaque()
has become UnsafeMutableRawPointer
.
(I couldn't have found an up-to-date Apple document, but you can check it easily in the Quick Help pane of Xcode.)
You have no need to convert:
context.info = Unmanaged.passUnretained(self).toOpaque()
Related Topics
Inter-App Data Migration (Migrating Data to New App Version)
Remove or Edit User Location Blue Pulsing Circle
Making Buttons Appear and Disappear When Clicked
How to Fix Cocoapod .Modulemap File Not Found
How to Convert Double to Int in Swift
What Does "Fatal Error: Unexpectedly Found Nil While Unwrapping an Optional Value" Mean
Protocol Doesn't Conform to Itself
Using a Dispatch_Once Singleton Model in Swift
Is Swift Pass by Value or Pass by Reference
Why Create "Implicitly Unwrapped Optionals", Since That Implies You Know There's a Value
How to Lock Orientation of One View Controller to Portrait Mode Only in Swift
How Does One Generate a Random Number in Swift
How to Get the Current Date in Short Format in Swift