如何在ARC下正确处理iPhone Core Foundation引用?

3
我对核心基础编程非常陌生,想知道我考虑的是否正确。我正在使用ARC,并不确定它如何处理非对象引用。我需要保存一个示例缓冲区的引用,并在应用程序中稍后使用它。这可行吗?还是示例缓冲区将在此之前被释放? 使用self.sampleBuffer = sampleBuffer_会导致内存泄漏吗?我需要在此调用后手动释放吗?
@property (nonatomic)CMSampleBufferRef sampleBuffer;

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer_ fromConnection:(AVCaptureConnection *)connection
{
    //does this cause memory leak?
    self.sampleBuffer = sampleBuffer_;
}
1个回答

2
它不会导致内存泄漏。实际上,你更有可能遇到从对象被释放的问题,因为属性默认具有assign属性,这意味着它们不会保留(即拥有)分配的对象。
如果你将示例缓冲区保留足够长的时间以使其成为属性,则应该遵循文档并将样本复制到自己的缓冲区中,而不是保留交给委托的对象:
如果你的应用程序由于保留提供的CMSampleBuffer对象时间过长而导致样本被丢弃,但它需要长时间访问样本数据,则应考虑将数据复制到新缓冲区中,然后释放样本缓冲区(如果先前被保留),以便可以重用它所引用的内存。
另一方面,如果你真的想保留对样本缓冲区的引用,你可以保持其他所有内容不变,并在将其分配给属性之前调用CFRetain对象(确保在之前CFRelease已分配的对象)。这具有与Foundation对象的strong属性等效的语义。

4
要明确的是,ARC对Core Foundation对象完全没有影响。它不会尝试自动管理它们,因此您需要手动管理它们。某些CF类型与Cocoa类型之间可以无缝桥接。由于ARC确实管理Cocoa对象,因此您需要仔细地在这些世界之间进行桥接。 - Ken Thomases
1
这并不像听起来那么难。如果你从一个CF函数(包括CG等)中获取它,它就在CF领域,因此不受ARC管理。你可以使用__bridge_transfer转换(或CFBridgingRelease)让ARC为你释放它。如果你从Cocoa或Cocoa Touch函数或方法中获取它,它就在Objective-C领域,因此由ARC管理。你可以使用__bridge_retained转换(或CFBridgingRetain)将其转移到CF世界,之后你必须使用CFRelease释放它(或将其转回ARC)。 - Peter Hosey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接