我正在使用Swift,并且注意到Swift不允许创建CFFunctionPointers。它只能绕过并引用现有的。
例如,CoreAudio需要对某些回调使用CFunctionPointer,因此我不能使用纯Swift。
所以我需要在这里使用一些Objective- C蹦床或包装器,将Swift闭包作为参数以及原始的回调原型,然后可以将其分配为回调,但是实际动作发生在Swift中,而不是Objective-C 。
我该怎么做呢?
此类包装程序的一些示例代码将帮助我理解如何以灵活的方式使用目标C中的Swift代码来实现此类目的,以解决无法创建CFunctionPointers的问题。
是的,我知道我可以随时在Objective- C中写东西。我想在纯粹的Swift中做为学习练习,将我的一个应用程序移植到Swift(使用了大量的CoreAudio / CoreVideo框架)。
我需要定义此回调:
typedef void (*MIDIReadProc) ( const MIDIPacketList *pktlist, void *readProcRefCon, void *srcConnRefCon );
我想尽可能地使用Objective-C。
这是我的方法:
MIDIReadProcCallback.h
#import <Foundation/Foundation.h> #import <AudioToolbox/AudioToolbox.h> typedef void (^OnCallback)(const MIDIPacketList *packetList); @interface MIDIReadProcCallback : NSObject + (void (*)(const MIDIPacketList *pktlist, void *readProcRefCon, void *srcConnRefCon))midiReadProc; + (void)setOnCallback:(OnCallback)onCallback; @end
MIDIReadProcCallback.m
#import "MIDIReadProcCallback.h" static OnCallback _onCallback = nil; static void readProcCallback(const MIDIPacketList *pktlist, void *refCon, void *connRefCon) { if (_onCallback) { _onCallback(pktlist); } } @implementation MIDIReadProcCallback + (void (*)(const MIDIPacketList *pktlist, void *readProcRefCon, void *srcConnRefCon))midiReadProc { return readProcCallback; } + (void)setOnCallback:(OnCallback)onCallback { _onCallback = onCallback; } @end
然后您可以注册MIDIReadProcCallback.midiReadProc为回调并设置处理程序MIDIReadProcCallback.setOnCallback({ (packetList: MIDIPacketList) in ... })
MIDIReadProcCallback.midiReadProc
MIDIReadProcCallback.setOnCallback({ (packetList: MIDIPacketList) in ... })