何时发布Core Foundation或核心图形对象?

时间:2018-02-19 08:21:56

标签: ios objective-c

我在iOS 10和iOS 11中使用核心图形和核心基础对象。我什么时候应该发布它?或者它会自动由ARC处理,我不应该打扰它吗?

原因是因为我释放CGDataProviderRef时应用程序崩溃了  使用CGDataProviderRelease(inputPDFDataProvider)

//file ref
CFURLRef pdfOutputURL = (  CFURLRef)CFBridgingRetain([NSURL fileURLWithPath:pdfOutputPath]);
CFDataRef inputPDFDataRef = (__bridge CFDataRef)inputFileData;
CGDataProviderRef inputPDFDataProvider = CGDataProviderCreateWithCFData(inputPDFDataRef);
CGPDFDocumentRef pdfRef = CGPDFDocumentCreateWithProvider(inputPDFDataProvider);
numberOfPages = CGPDFDocumentGetNumberOfPages(pdfRef);

// Release Core Graphics and Core Foundation Object
CGPDFDocumentRelease(pdfRef);
//    CGDataProviderRelease(inputPDFDataProvider); **// CRASHES When releasing this CoreGraphics object**
CFRelease(inputPDFDataRef);
CFRelease(pdfOutputURL);

3 个答案:

答案 0 :(得分:1)

与手动存储管理一样,所有权是决定性因素。来自Apple docs

  
      
  • 如果您创建一个对象(直接或通过制作另一个对象的副本 - 请参阅创建规则),您就拥有它。
  •   
  • 如果你从其他地方得到一个物品,你就不拥有它。如果您想防止它被处理掉,您必须将自己添加为所有者(使用CFRetain)。
  •   
  • 如果您是对象的所有者,则必须在使用完毕后放弃所有权(使用CFRelease)。
  •   

当且仅当您是对象的所有者时,才必须释放对象。

但您可以使用CFBridgingRelease将所有权转让给ARC。如果将此函数的结果分配给Objective C变量,则不再拥有该参数中的对象。

对于您的情况:您是inputPDFDataProvider的所有者,因为CGDataProviderCreateWithCFDataCreate Rule匹配:

  
      
  • 在名称中嵌入“创建”的对象创建函数;
  •   
  • 在名称中嵌入“复制”的对象复制功能。
  •   

因此,CGDataProviderRelease是正确的。但是,inputFileData的内存管理可能存在错误。

答案 1 :(得分:0)

'......它会自动由ARC处理,我不应该打扰它吗?'

答案是肯定的,你应该总是手动调用核心图形对象上的CFRelease来释放分配的内存。

关于你崩溃,如果你打电话给 CGDataProviderRelease ,它不应该粉碎 Apple文档(https://developer.apple.com/documentation/coregraphics/1408304-cgdataproviderrelease):

此函数等效于CFRelease,但如果provider参数为NULL则不会导致错误。

答案 2 :(得分:0)

您的inputPDFDataRef已通过__bridge inputFileData分配。因此,没有所有权转让,当您准备好它时, 发布inputPDFDataRef。它将在inputFileData发布时自动释放。

有关详细信息,请参阅this reference