Swift 2-UnsafeMutablePointer 反对

发布于 2021-01-31 23:57:02

如果我有类似的方法:

func someMethod(contextPtr: UnsafeMutablePointer<Void>)

我如何从中获取对象contextPtr

func someMethod(contextPtr: UnsafeMutablePointer<Void>){    
    let object:MyObject = contextPtr.memory
}

给出:

“无效”不能转换为“ MyObject”

秘诀是什么


更多详情:

我实际上在这里正在为以下操作设置全局回调函数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)
关注者
0
被浏览
309
1 个回答
  • 面试哥
    面试哥 2021-01-31
    为面试而生,有面试问题,就找面试哥。

    这应该起作用:将对象指针作为不透明的非托管指针传递给回调:

    context.info = UnsafeMutablePointer(Unmanaged.passUnretained(myObject).toOpaque())
    SCNetworkReachabilitySetCallback(reachability, callback, &context)
    

    并通过以下方式检索回调:

    func callback(reachability:SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutablePointer<Void>) {
    
        let myObject = Unmanaged<MyObject>.fromOpaque(COpaquePointer(info)).takeUnretainedValue()
    
    }
    

    当然,这假定只要安装了回调,就存在对该对象的某些强引用,因此不会释放该对象。

    更新: 请注意,如果您愿意使用“不安全”功能,则可以简化从对象指针到void指针以及返回的转换:

    context.info = unsafeAddressOf(myObject)
    // ...
    myObject = unsafeBitCast(info, MyObject.self)
    

    据我所知,生成的汇编代码是相同的。

    更新2: 另请参阅如何快速将自身转换为UnsafeMutablePointer
    <Void>类型,以获取有关“桥接”和此处可以使用的一些辅助函数的更多信息。


    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()
            // ...
        }
    }
    


推荐阅读
知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看