从C函数更新进度条

时间:2015-04-19 09:22:48

标签: c swift pointers grand-central-dispatch core-audio

我正在为Swift中的iOS 8开发音频应用。 加载MIDI文件,当用户按下“保存”按钮时,它将被渲染到手动拉取样本的C函数中的文件。
现在,我想更新界面中的进度条以进行此保存操作 我在ViewController的一个var中添加了一个属性观察器,我将一个指向这个var的指针传递给了C函数,希望它能在循环期间更新它...好吧,不。 即使C函数更新了循环内部var的值,此更新最后也会“触发”一次。 有没有办法更新进度条?
这是一些代码 谢谢!

在ViewController中:

var outProgressBarValue:Float = 0.0 {
    willSet {
        dispatch_async(dispatch_get_main_queue(), {
            println("New value received! -> \(newValue)")
            self.progressBarOutlet.setProgress(newValue, animated: true)
        })
    }
}

@IBAction func saveButton(sender: AnyObject) {
    [...]
    let backgroundQueue = dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)
    dispatch_async(backgroundQueue, {
        WriteOutputFile(url, self.musicSequence!, Sound.sharedInstance.musicPlayer, self.processingGraph,  &self.outProgressBarValue)

    dispatch_async(dispatch_get_main_queue(), {
            restoreOnlineRendering(processingGraph: self.processingGraph, mainMixerNode: self.mainMixerNode, ioNode: &(self.ioNode))
            self.saveButtonOutlet.setTitle("Done", forState: UIControlState.Normal)
    [...]
}

在链接的C文件中:

void WriteOutputFile(CFURLRef url, MusicSequence musicSequence, MusicPlayer musicPlayer, AUGraph processingGraph, float *outProgressBarValue) {  
[…] 
    CheckError(MusicPlayerStart(musicPlayer), "MusicPlayerStart");
    do {
        CheckError(AudioUnitRender (outputUnit, &actionFlags, &tStamp, 0, numFrames, bufferList), "AudioUnitRender");
        tStamp.mSampleTime += (Float64)numFrames;
        CheckError(ExtAudioFileWrite(outfile, numFrames, bufferList), "ExtAudioFileWrite");
        CheckError(MusicPlayerGetTime (musicPlayer, &currentTime), "MusicPlayerGetTime");
        *outProgressBarValue = currentTime / sequenceLength;
        printf("outProgressBarValue:\t %f\n", *outProgressBarValue);
    } while (currentTime < sequenceLength);

    CheckError(MusicPlayerStop(musicPlayer), "MusicPlayerStop"); 
[…] 
}  

1 个答案:

答案 0 :(得分:1)

如果观察不起作用,为什么不明确地将更新发送给控制器?例如,通过NSNotification。

以下是我作为概念证明所做的事情:

  1. 使用.h和.m文件添加Objective-C类文件。无需在此文件中定义类,只需将您的c函数放在.m中,然后将声明放在.h。

  2. 配置桥接标头,您可以在其中导入.h文件。桥接头通常称为“-Bridging-Header.h”。

  3. 您现在可以在任何快速课程中调用您的函数。

  4. 在带有c函数的.m文件中,导入“<UIKit/UIkit.h>”(或基础)。

  5. 如果需要,请发布与您的c函数类似的通知:

    NSNotification *notif = [[NSNotification alloc] initWithName:@"Update"
       object:nil userInfo:@{@"progress" : @0.42}];
    [[NSNotificationCenter defaultCenter] postNotification:notif];
    
  6. 在swift文件中,按照通常的步骤添加self作为通知的观察者,并使用userInfo字典中传递的值调用update函数。