swift pointers swift2

Swift 2-UnsafeMutablePointer<Void> al objeto



pointers swift2 (2)

Esto debería funcionar: pase el puntero del objeto como un puntero opaco no administrado a la devolución de llamada:

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

y recuperar en la devolución de llamada a través de:

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

Por supuesto, esto supone que existe una fuerte referencia al objeto siempre que la devolución de llamada esté instalada, de modo que el objeto no se desasigne.

Actualización: Tenga en cuenta que ambas conversiones del puntero de objeto a puntero vacío y viceversa pueden simplificarse si está dispuesto a usar funciones "inseguras":

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

El código de ensamblaje generado es, por lo que puedo ver, idéntico.

Actualización 2: Vea también Cómo lanzarse a sí mismo al tipo UnsafeMutablePointer <Void> en swift para obtener más información sobre el "puente" y algunas funciones auxiliares que se pueden usar aquí.

Actualización de 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() // ... } }

Si tengo un método como:

func someMethod(contextPtr: UnsafeMutablePointer<Void>)

¿Cómo obtengo el objeto del contextPtr ?

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

da:

''Void'' no es convertible a ''MyObject''

¿Cuál es la salsa secreta?

Mas detalle:

Lo que realmente estoy haciendo aquí es configurar una función de devolución de llamada global para SCNetworkReachability :

func callback(reachability:SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutablePointer<Void>) { let r:Reachability = info.memory }

y luego agregando la devolución de llamada de la siguiente manera:

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)


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

si necesitamos pasar como UnsafeMutablePointer self to async function

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