CMSampleBufferRef上的CFRelease - 为什么我需要调用它?

时间:2013-08-27 18:40:26

标签: iphone ios memory memory-leaks

CMSampleBufferRef sampleBuffer = [assetOutput copyNextSampleBuffer];
CMBlockBufferRef buffer = CMSampleBufferGetDataBuffer(sampleBuffer);
CMBlockBufferAppendBufferReference(_sem == 0 ? _buffer0 : _buffer1, buffer, 0, 0, 0);
//if(sampleBuffer)
//    CFRelease(sampleBuffer);

为什么这会导致第一行的内存泄漏(至少是Leaks所说的那样)?我有我的assetOutput.shouldAlwaysCopySampleOutput = NO。以下是我对情况的理解:

CMSampleBufferRef sampleBuffer = [assetOutput copyNextSampleBuffer];

此行将从assetOutput为样本缓冲区创建引用

CMBlockBufferRef buffer = CMSampleBufferGetDataBuffer(sampleBuffer);

此行将从CMSampleBuffer获取CMBlockBuffer,但不会分配新缓冲区,在这种情况下,Get方法意味着它是一个临时(自动释放)缓冲区

CMBlockBufferAppendBufferReference(_sem == 0 ? _buffer0 : _buffer1, buffer, 0, 0, 0);

此行将上面创建的CMBlockBuffer的引用附加到选定的全局范围缓冲区。它不会复制任何内存块。

因此,在这三行中,我都没有分配任何内存,也没有复制任何内存,它都是引用。我不明白泄漏的来源。我尝试添加注释掉的行,但它似乎仍然泄漏(尽管次数较少)

2 个答案:

答案 0 :(得分:6)

alwaysCopiesSampleData与内存管理无关。它只是关于你是在原始样本缓冲区上写字还是原始的克隆。遗憾的是,它有点名字。

copyNextSampleBuffer遵循创建规则,因此,应该在完成后释放。它创建一个保留计数至少为1的引用。

创建规则:

https://developer.apple.com/library/ios/DOCUMENTATION/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html#//apple_ref/doc/uid/20001148-103029

Apple的文档链接往往会发生变化,但如果上述链接消失,只需谷歌“创建规则”

答案 1 :(得分:1)

Core Foundation数据结构遵循与Foundation对象相同的所有权规则。

规则很简单 - 你创造(或通过其他方式获得所有权),你必须销毁。如果其他一些方法想要使用相同的结构/对象,它必须要求所有权,从而防止破坏。

取得所有权=“创造”/“保留”
释放所有权(“销毁”)=“释放”

在示例代码中,您使用copyNextSampleBuffer创建了一个结构。这意味着,您还必须使用CFRelease销毁它。

(请注意,使用ARC,您实际上看不到retainrelease调用,但使用Core Foundation,您必须明确地使用它们。