调用以下代码时,试图将“ self”快速传递给C函数:
var callbackStruct : AURenderCallbackStruct =
AURenderCallbackStruct.init(
inputProc: recordingCallback,
inputProcRefCon: UnsafeMutablePointer<Void>
)
在这里将“自我”转换为UnsafeMutablePointer类型的理想方法是什么?
一个对象的指针(即,实例 引用类型 )可以被转换为一个UnsafePointer<Void>
(的夫特映射const void *
,UnsafeRawPointer
在夫特3)和背部。在Objective-C中,您将编写
void *voidPtr = (__bridge void*)self;
//
MyType *mySelf = (__bridge MyType *)voidPtr;
(有关这些转换的确切含义,请参见Clang
ARC文档中的3.2.4桥接转换。)
Swift Unmanaged
为此具有一种类型。使用起来有点麻烦,因为它可以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严格类型系统时才需要“复杂”表达式。在编译的代码中,这只是指针之间的强制转换。(***
如果您愿意使用“不安全”的方法,可以按照注释中的说明将其写得更短一些,但是编译后的代码是相同的。)
使用此辅助方法,您可以将self
C函数传递为
let voidPtr = bridge(self)
(或者UnsafeMutablePointer<Void>(bridge(self))
如果C函数需要可变的指针),然后将其转换回对象指针(例如在回调函数中),如下所示:
let mySelf : MyType = bridge(voidPtr)
不会发生所有权转移,因此self
,只要使用void指针,就必须确保所有权存在。
为了完整起见,__bridge_retained
与__bridge_transfer
Objective-C 的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()
}
有关“不安全指针”的相关更改,请参见
问题内容: 我有一个映射到Swift的C函数定义为: 我正在尝试传递函数的路径并尝试过: 但是在path [i]上我得到了错误: ‘下标’不可用:不能下标Int范围的字符串 也不 也不管用 除了无法正常工作外,我认为还必须有一种更好,更轻松的方法来做到这一点。以前使用CString在StackOverflow上的答案似乎不再起作用。有什么建议? 问题答案: 使用CString在StackOverf
我的问题不是: < li >维护h2o数据帧的有效方法 < li>H2O运行速度比data.table R慢 < li >在h2o中加载大于内存大小的数据 硬件/空间: 32 个至强线程,带 ~256 GB 内存 要上传约 65 GB 的数据。(约56亿个细胞) 问题: 将数据上传到h2o需要几个小时。这不是任何特殊处理,只是“as.h2o(...)”。 使用“fread”将文本放入空间只需要不到
我刚刚更新到Xcode 6 beta 6,我的代码有以下问题,以前我的代码可以正常工作 提醒子对象的类型为AnyObject?!当我试图将其向下转换为字符串时,它会崩溃,并显示“Swift dynamic cast failure”消息。println打印的值是:可选(嘿,它的测试!) 所以问题是如何正确地投射任何对象?!斯威夫特?
问题内容: 我需要将jzy3d canvas强制转换为java.awt.component,我想使用JCombobox和按钮在框架中显示图表,但是当我要将画布强制转换为component时,程序被删除。谢谢您的回答。我已经尝试过了,对我没有帮助。 Launcher.java: ChartMode.java: 问题答案: 这为我工作。简单的解决方案,当我将jzy3d画布放到画布上并放入面板中时。
共享收货地址接口 wx.openAddress({ success: function (res) { var userName = res.userName; // 收货人姓名 var postalCode = res.postalCode; // 邮编 var provinceName = res.provinceName; // 国标收货地址第一级地址(省)
问题内容: 我正在尝试制作一个增长率()计算器,将结果四舍五入到最接近的整数并从那里重新计算,如下所示: 但到目前为止我一直做不到。 编辑 我有点是这样的: 尽管我不介意它总是四舍五入,但我不喜欢它,因为必须成为变量并在整个程序中进行更改(以便进行下一次计算),我不希望这种情况发生。 问题答案: 库中有一个可用项 (实际上在中 ,但是 在 大多数情况下您需要使用 导入 而不是 直接 使用 ) 。