如何将回调对象从 Swift 传递到 Objective C 类并用作回调?

Posted

技术标签:

【中文标题】如何将回调对象从 Swift 传递到 Objective C 类并用作回调?【英文标题】:How to pass callback object from Wwift to Objective C class and use as callback? 【发布时间】:2020-08-14 19:07:37 【问题描述】:

我正在尝试使用 Objective C 中的回调来回调到 Swift 类。我的实现有效,但是我试图将“self.callback(val)”回调移动到我的 AudioCallback 函数。我该怎么做?

我尝试在我的目标 c 类中创建一个全局变量,但不确定要使用什么类型,或者这是否是最佳实践。关于如何完成此任务的任何想法?

这是我的标题:

#import <Foundation/Foundation.h>

@interface Listener : NSObject

-(id)init;
- (void) startListner;

@property (nonatomic, copy) void(^callback)(Float32);

@end

这是我的目标 c 实现

#pragma mark MAIN CALLBACK
static void AudioCallback( Float32 * buffer, UInt32 frameSize, void * userData )

    
    
    //take only data from 1 channel
    Float32 zero = 0.0;
    vDSP_vsadd(buffer, 2, &zero, buffer, 1, frameSize*NUMCHANNELS);
    
    
    
    if (accumulateFrames(buffer, frameSize)==YES)  //if full
        
        //windowing the time domain data before FFT (using Blackman Window)
        if (windowBuffer==NULL)  windowBuffer = (Float32*) malloc(sizeof(Float32)*windowLength); 
        vDSP_blkman_window(windowBuffer, windowLength, 0);
        vDSP_vmul(dataAccumulator, 1, windowBuffer, 1, dataAccumulator, 1, accumulatorDataLenght);
        //=========================================
        
        
        Float32 maxHZValue = 0;
        Float32 maxHZ = strongestFrequencyHZ(dataAccumulator, fftConverter, accumulatorDataLenght, &maxHZValue);
        
        NSLog(@" max HZ = %0.3f ", maxHZ);
        dispatch_async(dispatch_get_main_queue(), ^ //update UI only on main thread
            //labelToUpdate.text = [NSString stringWithFormat:@"%0.3f HZ",maxHZ];
            //printf("", [NSString stringWithFormat:@"%0.3f HZ",maxHZ]);
            NSLog(@"Value of hello = %@", [NSString stringWithFormat:@"%0.3f HZ",maxHZ]);

            // call here
            self.callback(maxHz);
        );
        
        emptyAccumulator(); //empty the accumulator when finished
    
    memset(buffer, 0, sizeof(Float32)*frameSize*NUMCHANNELS);


@implementation Listener

-(id)init  return self; 

- (void) startListner
    NSLog(@"SomeMethod Ran");
    //labelToUpdate = HZValueLabel;
    
    //initialize stuff
    fftConverter = FFTHelperCreate(accumulatorDataLenght);
    initializeAccumulator();
    
    bool result = false;
    result = MoAudio::init( SAMPLE_RATE, FRAMESIZE, NUMCHANNELS, false);
    if (!result)  NSLog(@" MoAudio init ERROR"); 
    result = MoAudio::start( AudioCallback, NULL);
    
    if (!result)  NSLog(@" MoAudio start ERROR"); 
    
    self.callback(0.2)


@end

【问题讨论】:

【参考方案1】:

答案是将@implementation Listener 移动到我的类的顶部,然后设置一个指向我的调用类的指针:

...
@implementation Listener
Listener *mListener;
...

并且在init方法中,将监听器指针指向self:

...
-(id)init     
    mListener = self;
    return self;

...

最后,我可以使用 Listener 指针通过以下方式调用回调:

mListener.Callback(maxHZ);

希望这对像我一样困惑的人有所帮助。

【讨论】:

以上是关于如何将回调对象从 Swift 传递到 Objective C 类并用作回调?的主要内容,如果未能解决你的问题,请参考以下文章

从 Swift 调用 Objective C 和 C 传递回调函数

React Native 到 Swift 桥 - 传递参数和回调

如何将Object参数数组快速传递给Alamofire

如何将回调从父组件传递到嵌套路由组件?

Swift Object Mapper 传递不同的日期

如何将 Thymeleaf 对象从基本页面传递到 ajax 生成页面?