一尘不染

用于快速关闭的CFunctionPointer的Objective-C包装器

swift

我正在使用Swift,并且注意到Swift不允许创建CFFunctionPointers。它只能绕过并引用现有的。

例如,CoreAudio需要对某些回调使用CFunctionPointer,因此我不能使用纯Swift。

所以我需要在这里使用一些Objective-
C蹦床或包装器,将Swift闭包作为参数以及原始的回调原型,然后可以将其分配为回调,但是实际动作发生在Swift中,而不是Objective-C 。

我该怎么做呢?

此类包装程序的一些示例代码将帮助我理解如何以灵活的方式使用目标C中的Swift代码来实现此类目的,以解决无法创建CFunctionPointers的问题。

是的,我知道我可以随时在Objective-
C中写东西。我想在纯粹的Swift中做为学习练习,将我的一个应用程序移植到Swift(使用了大量的CoreAudio / CoreVideo框架)。


阅读 173

收藏
2020-07-07

共1个答案

一尘不染

我需要定义此回调:

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 ... })

2020-07-07