Как передать объект обратного вызова из Wwift в класс Objective C и использовать в качестве обратного вызова?

#objective-c #swift #bridging-header

#objective-c #swift #мостовой заголовок

Вопрос:

Я пытаюсь использовать обратный вызов в Objective C для обратного вызова класса Swift. Моя реализация работает, однако я пытаюсь переместить обратный вызов «self.callback (val)» в мою функцию AudioCallback. Как я могу это сделать?

Я пытался создать глобальную переменную в своем классе objective c, но не уверен, какой тип вообще использовать, и является ли это наилучшей практикой. Есть идеи о том, как я могу это выполнить?

Вот мой заголовок:

 #import <Foundation/Foundation.h>

@interface Listener : NSObject

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

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

@end
  

Вот моя реализация objective 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, amp;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, amp;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;
}
...
  

Наконец, я мог бы использовать указатель прослушивателя для вызова обратного вызова через:

 mListener.Callback(maxHZ);
  

Надеюсь, это поможет всем, кто был в таком же замешательстве, как и я.