以下func是Core Audio
中MusicSequence的一部分func MusicSequenceSetUserCallback(_ inSequence: MusicSequence, _ inCallback: MusicSequenceUserCallback?, _ inClientData: UnsafeMutablePointer<Void>) -> OSStatus
MusicSequenceUserCallback在API中定义为:
typealias MusicSequenceUserCallback = (UnsafeMutablePointer<Void>, MusicSequence, MusicTrack, MusicTimeStamp, UnsafePointer<MusicEventUserData>, MusicTimeStamp, MusicTimeStamp) -> Void
我不清楚如何将自定义函数传递给MusicSequenceSetUserCallback。知道了Swift中的func类型,我使用与MusicSequenceUserCallback
完全相同的参数创建了一个自定义函数,并尝试将其设置为:
var argFunc: MusicSequenceUserCallback = myCallback
但我在上面的代码行中收到错误A C function pointer can only be formed from a reference to a 'func' of a literal closure
。
修改
这是我写的回电话:
func myCallback(inClientData: UnsafeMutablePointer<Void>, sequence: MusicSequence, track: MusicTrack, eventTime: MusicTimeStamp, data: UnsafePointer<MusicEventUserData>, startSliceBeat: MusicTimeStamp, endSliceBeat: MusicTimeStamp) -> Void {
// do something
}
答案 0 :(得分:2)
您收到错误是因为回调需要是一个自由函数,或者一个没有任何捕获本地上下文的闭包。实例方法捕获self
引用,因此您不能将它们用作回调。
解决方案是:
myCallBack
声明为全局函数,或myCallback
声明为内部函数/闭包,并确保它不会捕获任何局部变量如果您需要在回调中使用类的实例成员,可以通过inClientData
参数将回调从free函数转发到类的实例来实现:
class MyMusicClass {
func myCoreAudioFunction() {
.............
func seqCB(inClientData: UnsafeMutablePointer<Void>, sequence: MusicSequence, track: MusicTrack, eventTime: MusicTimeStamp, data: UnsafePointer<MusicEventUserData>, startSliceBeat: MusicTimeStamp, endSliceBeat: MusicTimeStamp) -> Void {
// we know for sure we have a MyMusicClass instance here, so the cast should be OK
// care to be taken though to unregister the callback if the `MyMusicClass` instance gets deallocated, to avoid the zombie
let client = unsafeBitCast(inClientData, MyMusicClass.self)
client.musicSeqenceCallback(sequence, track: track, eventTime: eventTime, data: data, startSliceBeat: startSliceBeat, endSliceBeat: endSliceBeat)
}
MusicSequenceSetUserCallback(myMusicSequence,seqCB, unsafeBitCast(self, UnsafeMutablePointer<Void>.self))
}
func musicSeqenceCallback(sequence: MusicSequence, track: MusicTrack, eventTime: MusicTimeStamp, data: UnsafePointer<MusicEventUserData>, startSliceBeat: MusicTimeStamp, endSliceBeat: MusicTimeStamp) -> Void {
// do anything you want here, there are no more restrictions :)
}
}