尝试将“self”传递给swift中的C函数,当调用以下代码时:
var callbackStruct : AURenderCallbackStruct = AURenderCallbackStruct.init( inputProc: recordingCallback,inputProcRefCon: UnsafeMutablePointer<Void> )
在这里将“self”转换为UnsafeMutablePointer类型的理想方法是什么?
对象指针(即引用类型的实例)可以是
转换为UnsafePointer< void> (Swift 3中的const void *,UnsafeRawPointer的Swift映射)并返回。在Objective-C中,你会写
转换为UnsafePointer< void> (Swift 3中的const void *,UnsafeRawPointer的Swift映射)并返回。在Objective-C中,你会写
void *voidPtr = (__bridge void*)self; // MyType *mySelf = (__bridge MyType *)voidPtr;
(有关这些的确切含义,请参阅Clang ARC文档中的3.2.4 Bridged casts
管型。)
Swift有一个非管理类型用于此目的。
使用它有点麻烦,因为它适用于COpaquePointer
而不是UnsafePointer< Void> ;.这里有两种帮助方法
(以Objective-C __bridge演示命名):
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) // *** }
“复杂”的表达方式只适用于Swifts
严格型系统在编译代码中,这只是一个演员
指针之间。 (可以写在***的注释中所示的较短
如果你愿意使用“不安全”的方法,而是编译的
代码是一样的)
let voidPtr = bridge(self)
(或UnsafeMutablePointer< Void>(bridge(self))如果C函数需要
一个可变指针),并将其转换回一个对象指针 – 例如
在一个回调函数 – as
let mySelf : MyType = bridge(voidPtr)
不会转让所有权,所以你必须确保自我
只要使用void指针就存在。
为了完整起见,从Objective-C开始的__bridge_retained和__bridge_transfer的Swift将相当于
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()将对象指针转换为void指针
保留对象。 bridgeTransfer()转换
void指针返回一个对象指针并消耗保留。
一个优点是该对象不能被释放
电话是因为强烈的参考。缺点是
呼叫必须适当平衡,并且可以轻松导致保留
周期。
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() }
对“不安全指针”的相关更改如下所述
> SE-0017 Change Unmanaged to use UnsafePointer
> SE-0107 UnsafeRawPointer API