【问题标题】:Transitioning Audio Unit code to ARC将音频单元代码转换为 ARC
【发布时间】:2012-03-17 08:08:09
【问题描述】:

抱歉,如果这太含糊了...这是我在这里的第一篇文章,我真的很困惑这个问题!

我一直在尝试将使用音频单元的 iOS Xcode 项目转换为 ARC,但它似乎破坏了音频单元处理类的功能。一些症状...当我尝试在 AUProcessor.mm 中引用“self”时,AUProcessor 类被称为“const*”,而在 ARC 之前的版本中,没有提到“const*”。

指向“self”的指针会产生以下错误:

callbackStruct.inputProcRefCon = self;

[error] Assigning to 'void *' from incompatible type 'AUProcessor *const __strong'.

我可以通过在 self 前面添加 (__bridge void*) 来消除错误,这样可以编译项目。但是,音频单元处理器在应用程序中不起作用。

就类的引用方式而言,我在代码的其他地方看不到任何与 ARC 之前的版本有显着差异的地方。

如果需要更多上下文,请告诉我。

提前致谢!!

(顺便说一句,感谢这些论坛的所有贡献者......对于热心但缺乏经验的程序员来说,它们确实是一个很好的资源!)

【问题讨论】:

    标签: ios xcode4.2 automatic-ref-counting core-audio


    【解决方案1】:

    通常,(__bridge void*) 将是此处的正确演员表。这意味着“在不应用任何内存管理的情况下获取指向该对象的指针;我保证只要需要,我就会一直保留它。” (最后一部分只是暗示,但如果你不这样做,你会崩溃。)

    您确定self 会在此音频单元期间继续存在吗?如果没有任何东西对self 有强引用,那么它将消失,inputProcRefCon 将成为一个悬空指针。

    当您说“在应用中不起作用”时,您是什么意思?它会崩溃吗?回调不会发生吗?回调发生时,它没有正确的数据吗?

    【讨论】:

    • 感谢您的 cmets 到目前为止 Rob。该应用程序基于来自sleepyleaf.com 的 pitchDetector 教程。 AUProcessor (RIOInterface) 类包含用于启动和分析音频流的多种方法,例如 FFT 以确定音高。然后该类返回显示在屏幕上的值。在我尝试 ARC 转换之后,与该类相关的音频流和其他所有内容似乎都没有正确启动。没有音频缓冲区通过等,直到我尝试停止音频流,当应用程序崩溃时。
    • 感谢 Rob,这帮助我使 SpeakHere 示例与 ARC 兼容。我觉得我以前也来过这里,但后来我会留下评论,所以我猜不是;)+1
    【解决方案2】:

    下面的代码适用于我的 MusicPlayer API。我不知道它是否正确,但我没有收到任何错误或内存泄漏。希望对您有所帮助!

    // 分配回调:

     MusicSequenceSetUserCallback( sequence, MyEventCallback, (__bridge_retained void *)self );
    

    //回调方法:

    void  MyEventCallback(void                      *inClientData,
                      MusicSequence             inSequence,
                      MusicTrack                    inTrack,
                      MusicTimeStamp                inEventTime,
                      const MusicEventUserData  *inEventData,
                      MusicTimeStamp                inStartSliceBeat,
                      MusicTimeStamp                inEndSliceBeat)
    {
    
    struct MyMusicEventUserData* userEventData = ( MyMusicEventUserData *)inEventData;
    
    [(__bridge MusicPlayerController*)inClientData MIDIEvent:userEventData 
                                                   eventTime:inEventTime 
                                              startSliceBeat:inStartSliceBeat 
                                                endSliceBeat:inEndSliceBeat];
    }
    

    【讨论】:

    • 这是过度保留self,这将导致它泄漏。在此处使用__bridge_retainedself 的所有权转移给void*(即添加+1 保留)。你永远不会用释放来平衡它,所以对象被泄露了。但是,这可行,这表明系统中没有其他任何东西具有指向该对象的强指针,这更有可能是您的问题。您通常不应该要求 AU 系统为您保留它,但如果您这样做,您需要确保在 AU 系统完成后释放它。
    • 真的吗?我有一个UIViewController,它包含一个strongMusicPlayerController 的引用(即上面的self)。也许我没有看到任何问题,因为 UIViewController + MusicPlayerController 在应用程序的整个生命周期中都存在?我会试试(__bridge void*)
    • 过度保留不会泄漏任何与整个应用具有相同生命周期的对象。
    【解决方案3】:

    我设法通过使用编译器标志 -fno-objc-arc 从 ARC 中排除麻烦的类来解决我的问题。

    这不是一个非常令人满意的结论,但至少我的应用程序又可以工作了……看来我需要了解更多关于内存管理的知识!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-12
      • 1970-01-01
      • 2015-08-12
      • 1970-01-01
      • 1970-01-01
      • 2016-01-31
      • 2017-07-04
      相关资源
      最近更新 更多