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的引用附加到选定的全局范围缓冲区。它不会复制任何内存块。
因此,在这三行中,我都没有分配任何内存,也没有复制任何内存,它都是引用。我不明白泄漏的来源。我尝试添加注释掉的行,但它似乎仍然泄漏(尽管次数较少)
答案 0 :(得分:6)
alwaysCopiesSampleData
与内存管理无关。它只是关于你是在原始样本缓冲区上写字还是原始的克隆。遗憾的是,它有点名字。
copyNextSampleBuffer
遵循创建规则,因此,应该在完成后释放。它创建一个保留计数至少为1的引用。
创建规则:
Apple的文档链接往往会发生变化,但如果上述链接消失,只需谷歌“创建规则”答案 1 :(得分:1)
Core Foundation数据结构遵循与Foundation对象相同的所有权规则。
规则很简单 - 你创造(或通过其他方式获得所有权),你必须销毁。如果其他一些方法想要使用相同的结构/对象,它必须要求所有权,从而防止破坏。
取得所有权=“创造”/“保留”
释放所有权(“销毁”)=“释放”
在示例代码中,您使用copyNextSampleBuffer
创建了一个结构。这意味着,您还必须使用CFRelease
销毁它。
(请注意,使用ARC,您实际上看不到retain
和release
调用,但使用Core Foundation,您必须明确地使用它们。