我注意到我的AVAssetReader(在这种情况下为reader)的retainCount随此代码而继续增加。我相信我会适当地释放我应有的一切。有没有办法检查CMSampleBufferRef引用计数?有人看到我忘了发布的东西吗?

AVAssetReaderTrackOutput* trackOutput = (AVAssetReaderTrackOutput*)[reader.outputs objectAtIndex:0];
NSLog(@"PreReader Count: %d", reader.retainCount);
CMSampleBufferRef sampleBufferRef = [trackOutput copyNextSampleBuffer];
NSLog(@"Reader Count: %d", reader.retainCount);  //retainCount has increased by 1
if (sampleBufferRef) {

    CopySampleBufferToStream(sampleBufferRef, stream);

    CMSampleBufferInvalidate(sampleBufferRef);
    CFRelease(sampleBufferRef); //Retain count doesn't go back down, item hasn't been deleted?
}

以此作为CopySampleBufferToStream的关键公园
void CopySampleBufferToStream(CMSampleBufferRef sampleBufferRef, cSoundStream* stream)
{
    CMBlockBufferRef blockBufferRef = CMSampleBufferGetDataBuffer(sampleBufferRef);
    size_t length = CMBlockBufferGetDataLength(blockBufferRef);

    do
    {
        //...

        OSStatus result = CMBlockBufferCopyDataBytes(blockBufferRef, startOffset, copyLength, (stream->mSrcBuffers[stream->mActiveWriteIdx].mData + stream->mSrcBuffers[stream->mActiveWriteIdx].mBufferOffset));

        //...

    } while(stream->ContinueLoading() && stream->TransitionNotReady() && copyLength < length);

}

编辑:

因此,在进一步调试之后,我能够确认在退出循环并清除了自动释放池之后,AVAssetReader确实降至了keepCount为1

我将池版本移到了读者版本之前进行了测试...
[pool release];
NSLog(@"Reader Count: %d", reader.retainCount);
[reader release];

我得到了一个retainCount为1的预期结果。

但是,随着FigSampleBuffer的存在,内存似乎仍从CMSampleBufferRefs泄漏。这是我在Instruments中找到的内容:

和导致CMSampleBufferRef ...的调用堆栈

这是在我退出循环之后,清理了所有内容,然后为另一个AVAset重新创建了它。当我重复此操作时,每个爆头中都会出现更多FigSampleBuffer。

最佳答案

不要调用retainCount;这是没有用的。

在内存管理方面,该代码没有任何明显的错误。

真正的问题是;您是否平衡了所有保留和发布?如果是这样,您就完成了。

如果有,并且看到无限的内存增长,请提交一个错误。

在任何给定时间,绝对的retainCount都是实现细节,该值很可能会以超出您控制范围的方式反射(reflect)内部实现细节。此外,retainCount永远不会反射(reflect)对象当前是否在自动释放池中。

仅可以绝对知道retainCount的时间是:

  • 您实现了一个新的根类(NSObject子类起作用,但仅出于巧合)
  • 您不会自动释放
  • 实例
  • 您不将对象传递给任何系统API
  • 09-28 07:17