Swift 2-非女性化指针<;无效>;反对

Swift 2-非女性化指针<;无效>;反对,swift,pointers,swift2,Swift,Pointers,Swift2,如果我有如下方法: func someMethod(contextPtr: UnsafeMutablePointer<Void>) 给出: “Void”不能转换为“MyObject” 什么是秘方 更多详情: 我在这里实际做的是为SCNetworkReachability设置一个全局回调函数: func callback(reachability:SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: Unsa

如果我有如下方法:

func someMethod(contextPtr: UnsafeMutablePointer<Void>)
给出:

“Void”不能转换为“MyObject”

什么是秘方


更多详情:

我在这里实际做的是为
SCNetworkReachability
设置一个全局回调函数:

func callback(reachability:SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutablePointer<Void>) {

    let r:Reachability = info.memory
}

应该可以这样做:将对象指针作为不透明的非托管指针传递 要返回回调,请执行以下操作:

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()

}
就我所见,生成的汇编代码是相同的

更新2:有关更多信息,请参见 关于“桥接”和一些可以在这里使用的辅助函数


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()
        // ...
    }
}
var context=SCNetworkReachabilityContext(版本:0,信息:nil,保留:nil,发布:nil,副本描述:nil)
context.info=unsafemeutablerawpointer(Unmanaged.passUnretained(self).toOpaque())
// ...
func回调(可访问性:SCNetworkReachability,标志:SCNetworkReachabilityFlags,信息:UnsafeMutableRawPointer?){
如果let info=info{
让myObject=Unmanaged.from不透明(info).takeUnrepainedValue()
// ...
}
}
结构{
变量i:Int=10
}
var first=S()
func-foo(contextPtr:UnsafeMutablePointer){
设pS=unsafemeutablepointer(contextPtr)
pS.memory.i=100
}
打印(first.i)//10
foo(&第一)
打印(first.i)//100
如果我们需要作为不可配置指针self传递给异步函数

import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

import Foundation
// can be struct, class ...
class C {
    let queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT)
    var s: String = ""
    func foo() {
        var c = self
        dispatch_async(queue) { () -> Void in
            f(&c)
        }

    }
}

func f(pV: UnsafeMutablePointer<Void>) {
    let pC = UnsafeMutablePointer<C>(pV)
    sleep(1)
    print(pC.memory.s)
}

var c1: C? = C()
c1!.s = "C1"
c1!.foo()        // C1
var c2: C? = C()
c2!.s = "C2"
c2!.foo()        // C2
c1 = nil
c2 = nil
print("test")
导入
XCPlaygroundPage.currentPage.needsIndefiniteExecution=true
进口基金会
//可以是结构、类。。。
C类{
让queue=dispatch\u queue\u create(“测试”,dispatch\u queue\u并发)
var s:String=“”
func foo(){
var c=自我
调度异步(队列){()->Void in
f&c
}
}
}
func f(pV:UnsafeMutablePointer){
设pC=不可配置指针(pV)
睡眠(1)
打印(pC.memory.s)
}
变量c1:C?=C()
c1!。s=“C1”
c1!。foo()//C1
变量c2:C?=C()
c2!。s=“C2”
c2!。foo()//C2
c1=零
c2=零
打印(“测试”)

调用该方法时传递什么?为什么它会作为void指针传递呢?我试着简化一下代码——我添加了更多detail@AshleyMills:很高兴看到您可以在您的可达性项目中使用它!这是解开谜题的最后一把钥匙!刚刚注意到你的更新。好主意,但不幸的是,这对我试图解决的问题不起作用,因为
unsafeAddressOf
需要
AnyObject
,而
SCNetworkReachabilityContext
是一个
struct
很好的解决方案。我很惊讶我花了这么长时间才找到这个。考虑到某些低级API依赖于不安全的指针,你会认为很多人需要知道这一点@是的,这是乔:看来我用Swift.org上的swift3预览版更新了代码。它现在是用Xcode 8编译的,你能再检查一下吗?谢谢你的反馈!但是,您的示例代码与问题不同,因为
C.foo()
同步调用
f()
,所以
C
保持分配状态。在最初的问题中,
f()
是一个异步回调函数,因此在调用
f()
之前将释放
c
context.info = unsafeAddressOf(myObject)
// ...
myObject = unsafeBitCast(info, MyObject.self)
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()
        // ...
    }
}
struct S {
    var i: Int = 10
}
var first = S()

func foo(contextPtr: UnsafeMutablePointer<Void>){
    let pS = UnsafeMutablePointer<S>(contextPtr)
    pS.memory.i = 100
}
print(first.i) // 10
foo(&first)
print(first.i) // 100
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

import Foundation
// can be struct, class ...
class C {
    let queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT)
    var s: String = ""
    func foo() {
        var c = self
        dispatch_async(queue) { () -> Void in
            f(&c)
        }

    }
}

func f(pV: UnsafeMutablePointer<Void>) {
    let pC = UnsafeMutablePointer<C>(pV)
    sleep(1)
    print(pC.memory.s)
}

var c1: C? = C()
c1!.s = "C1"
c1!.foo()        // C1
var c2: C? = C()
c2!.s = "C2"
c2!.foo()        // C2
c1 = nil
c2 = nil
print("test")