【问题标题】:Obj-C objects not being released in a C callback function未在 C 回调函数中释放 Obj-C 对象
【发布时间】:2014-06-10 10:12:43
【问题描述】:

我在我的应用程序中使用AudioFileOpenWithCallbacks 函数以块的形式提供 MP3 数据。我调用函数如下:

AudioFileOpenWithCallbacks((__bridge void *)(self), TTMAudioFile_ReadProc, NULL, TTMAudioFile_GetSizeProc, NULL, 0, &aqData.mAudioFile);

在这种情况下,self 是包含的 Objective-C 类。

我的TTMAudioFile_ReadProc回调函数如下:

OSStatus TTMAudioFile_ReadProc(void *inClientData, SInt64 inPosition, UInt32 requestCount, void *buffer, UInt32 *actualCount) {

    TTMAudioQueuePlayer *this = (__bridge TTMAudioQueuePlayer *)inClientData;
    NSData *data = [this.decryptor dataAtOffset:inPosition length:requestCount error:NULL];
    memcpy(buffer, data.bytes, data.length);

    NSUInteger length = data.length;
    *actualCount = (UInt32)length;

    return noErr;
}

这可行,但 NSData 没有被发布。 Instruments 中的 Profiling Allocations 揭示了许多如下所示的分配:

显然在我的回调函数中有两个额外的retain 调用,但我看不出我可以在哪里保留它们。此外,我正在使用 ARC,所以我也不知道为什么会这样。

【问题讨论】:

  • 如果不看更多代码,这真的很难调试。 dataAtOffset 是做什么的?

标签: objective-c c automatic-ref-counting core-audio audioqueueservices


【解决方案1】:

我需要一个自动释放池。

C 回调函数TTMAudioFile_ReadProc 在与主线程不同的线程上调用。在这种情况下,不会自动创建自动释放池,这与使用调度队列时不同。

OSStatus TTMAudioFile_ReadProc(void *inClientData, SInt64 inPosition, UInt32 requestCount, void *buffer, UInt32 *actualCount) {
    @autoreleasepool {
        TTMAudioQueuePlayer *this = (__bridge TTMAudioQueuePlayer *)inClientData;
        NSData *data = [this.decryptor dataAtOffset:inPosition length:requestCount error:NULL];

        memcpy(buffer, data.bytes, data.length);
        NSUInteger length = data.length;
        *actualCount = (UInt32)length;

        return noErr;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-05
    相关资源
    最近更新 更多