2012-06-14 57 views
2

我有这个方法(别人写的!)如何正确释放CF对象对象?

- (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创建或复制CF函数名称来释放所有东西。我不明白的是我如何发布pdf,并仍然能够在函数结束时返回它。 我错过了什么? 谢谢。

回答

5

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

它也命名约定,那些返回CF对象的功能应与createcopy

+0

谢谢。所以当CGPDFDocumentRef对象在最后返回时,其保留计数不会改变,对吧?它仍然是一个,它是来电者的责任,使它成为0(使用它之后) – TrekOnTV2017

+0

是的,这是正确的。 –

3

既然你想回到你在你的函数创建一个对象据此命名,本身的功能应适当命名以表明它正在返回的对象应该被释放。

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

+0

有趣,谢谢。所以我只是通过命名函数createPdf或copyPdf“修复”了内存泄漏警告? – TrekOnTV2017

+2

'copyPDF'和'createPDF'都暗示该函数做的事情不是它所做的。仅仅将“复制”一词添加到与复制无关的函数中并不符合内存管理规则的精神。 – Chuck

+0

是的,我已经将函数重命名为createPdf,但仍然得到相同的三条内存泄漏警告。 – TrekOnTV2017

-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]; 
} 

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