3
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的引用附加到选定的全局范围缓冲区。它不会复制任何内存块。

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

4

2 回答 2

6

alwaysCopiesSampleData is not about memory management. It is only about whether you are scribbling on the original sample buffer or a clone of the original. It is somewhat unfortunately named.

copyNextSampleBuffer follows the create rule and as such, should be released when you are done with it. It creates a reference with a retain count of at least 1.

The Create Rule:

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

Apple's doc links tend to change, but if the above link dies, just google "The Create Rule"

于 2013-08-27T18:46:16.013 回答
2

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

规则非常简单——无论您创建什么(或通过其他方式获得所有权),您都必须销毁。如果其他方法想要使用相同的结构/对象,它必须请求所有权,从而防止破坏。

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

在您的示例代码中,您使用copyNextSampleBuffer. 这意味着,您还必须使用CFRelease.

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

于 2013-08-27T18:47:28.067 回答