简体   繁体   English

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

[英]CFRelease on CMSampleBufferRef - Why do I need to call this?

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

Why does this cause a memory leak at the first line (at least that's where Leaks suggests)? 为什么这会导致第一行的内存泄漏(至少是Leaks所说的那样)? I have my assetOutput.shouldAlwaysCopySampleOutput = NO. 我有我的assetOutput.shouldAlwaysCopySampleOutput = NO。 Here's my understanding of the situation: 以下是我对情况的理解:

CMSampleBufferRef sampleBuffer = [assetOutput copyNextSampleBuffer];

This line will create a reference to the sample buffer from the assetOutput. 这条线将创建从assetOutput样品缓冲液的参考

CMBlockBufferRef buffer = CMSampleBufferGetDataBuffer(sampleBuffer);

This line will get the CMBlockBuffer from the CMSampleBuffer but will not allocate a new buffer, and the Get method in this case means it is a temporary (autoreleased) buffer 这一行将从CMSampleBuffer获取CMBlockBuffer,但不会分配新缓冲区,在这种情况下,Get方法意味着它是一个临时(自动释放)缓冲区

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

This line will append the reference of the CMBlockBuffer created above, to the selected global-scope buffer. 该行将上面创建的CMBlockBuffer的引用附加到选定的全局范围缓冲区。 It will not copy any memory blocks. 它不会复制任何内存块。

So in none of these three lines do I allocate any memory nor do I copy any memory, it's all references. 因此,在这三行中,我都不会分配任何内存,也不会复制任何内存,这些都是引用。 I don't understand where the leak is coming from. 我不明白泄漏的来源。 I tried adding the commented out lines and it still seems to leak (although fewer times) 我尝试添加注释掉的行,它似乎仍然泄漏(尽管次数较少)

alwaysCopiesSampleData is not about memory management. alwaysCopiesSampleData与内存管理alwaysCopiesSampleData 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. copyNextSampleBuffer遵循创建规则,因此,应该在完成后释放。 It creates a reference with a retain count of at least 1. 它创建一个保留计数至少为1的引用。

The Create Rule: 创建规则:

https://developer.apple.com/library/ios/DOCUMENTATION/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html#//apple_ref/doc/uid/20001148-103029 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" Apple的文档链接往往会发生变化,但如果上述链接消失,只需谷歌“创建规则”

Core Foundation data structures follows the same ownership rules as Foundation objects. Core Foundation数据结构遵循与Foundation对象相同的所有权规则。

The rules are pretty simple - whatewer you create (or get the ownership by some other way), you have to destroy. 规则很简单 - 你创造(或通过其他方式获得所有权),你必须销毁。 If some other method wants to work with the same structure/object, it has to ask for the ownership and thus preventing the destruction. 如果某些其他方法想要使用相同的结构/对象,则必须要求所有权,从而防止破坏。

Taking ownership = "create" / "retain" 取得所有权=“创造”/“保留”
Releasing ownership ("destruction") = "release" 释放所有权(“销毁”)=“释放”

In your sample code, you have created a structure using copyNextSampleBuffer . 在示例代码中,您使用copyNextSampleBuffer创建了一个结构。 That means, you have to also destroy it using CFRelease . 这意味着,您还必须使用CFRelease销毁它。

(Note that with ARC you don't actually see the retain and release calls but with Core Foundation, you have to use them explicitely). (请注意,使用ARC,您实际上看不到retainrelease调用,但使用Core Foundation,您必须明确地使用它们)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM