2

我有这个方法(别人写的!)

- (CGPDFDocumentRef)getPdf {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    NSString *documentsDirectory = [paths objectAtIndex:0];

    NSString *pdfPath = [documentsDirectory stringByAppendingPathComponent:@"myLocalFileName.pdf"];

    NSURL *pdfURL = [NSURL fileURLWithPath:pdfPath];

    CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL);

    return pdf;
}

现在,我运行了分析并收到三个内存泄漏警告:

Call to function 'CGPDFDocumentCreateWithURL' returns a Core Foundation object with a +1 retain count
Object returned to caller as an owning reference (single retain count transferred to caller)
Object leaked: object allocated and stored into 'pdf' is returned from a method whose name ('getPdf') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'.  This violates the naming convention rules given in the Memory Management Guide for Cocoa

有人可以告诉我这里需要/应该做什么吗?我知道我应该在 CF 函数名称中使用 create 或 copy 来 CFRelease 一切。我不明白的是如何释放 pdf 并且仍然能够在函数结束时返回它。我错过了什么?谢谢你。

4

4 回答 4

6

您需要如下所示的 clang 源注释http://cocoasamurai.blogspot.com/2012/01/clang-source-annotations.html

    #import <AppKit/AppKit.h>
@interface NSColor (CWNSColorAdditions)
-(CGColorRef)cw_cgColor CF_RETURNS_RETAINED;
@end
于 2012-06-17T17:59:45.537 回答
5

接收 pdf 的代码在完成后有责任 CFRelease 它。与 Cocoa 不同,CF 不支持自动释放,因此任何从 CF 函数返回的对象都是调用者拥有且必须处理的对象。

这也是命名约定,那些返回 CF 对象的函数应该相应地命名为createorcopy

于 2012-06-14T17:30:02.493 回答
3

由于您要返回在函数中创建的对象,因此应正确命名函数本身以指示应释放它返回的对象。

而不是getPdf,您可以调用您的函数createPdfcopyPdf. 这将告诉调用者它应该CFRelease在完成时调用,并且还满足分析的请求。

于 2012-06-14T17:30:54.900 回答
-1
- (CGPDFDocumentRef)getPdf {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    NSString *documentsDirectory = [paths objectAtIndex:0];

    NSString *pdfPath = [documentsDirectory stringByAppendingPathComponent:@"myLocalFileName.pdf"];

    NSURL *pdfURL = [NSURL fileURLWithPath:pdfPath];

    CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL);

    return [pdf autorelease];
}

我认为这可以解决您的问题。

于 2014-06-06T07:46:31.420 回答