Swift 2 - UnsafeMutablePointer<Void>反对 [英] Swift 2 - UnsafeMutablePointer<Void> to object
问题描述
如果我有这样的方法:
func someMethod(contextPtr: UnsafeMutablePointer<Void>)
如何从 contextPtr
获取对象?
func someMethod(contextPtr: UnsafeMutablePointer<Void>){
let object:MyObject = contextPtr.memory
}
给出:
'Void' 不能转换为 'MyObject'
'Void' is not convertible to 'MyObject'
秘诀是什么
更多细节:
我在这里实际做的是为 SCNetworkReachability
设置一个全局回调函数:
What I'm actually doing here is setting up a global callback function for SCNetworkReachability
:
func callback(reachability:SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutablePointer<Void>) {
let r:Reachability = info.memory
}
然后添加回调如下:
var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
var s = self
withUnsafeMutablePointer(&s) {
context.info = UnsafeMutablePointer($0)
}
SCNetworkReachabilitySetCallback(reachability, callback, &context)
推荐答案
这应该有效:将对象指针作为不透明的非托管指针传递到回调:
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.
更新: 请注意,从对象指针到 void 指针的两种转换如果您愿意使用不安全"功能,则可以简化并返回:
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.
更新 2:另见 如何将 self 转换为 UnsafeMutablePointer
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 更新(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()
// ...
}
}
这篇关于Swift 2 - UnsafeMutablePointer<Void>反对的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!