苹果手机 。结束,关闭和释放CGContext

时间:2011-03-31 20:39:57

标签: iphone

我有一种在iPhone上创建PDF的方法。

方法就像这样开始

CGContextRef pdfContext = [self createPDFContext...]
// this line creates a CGContextRef that I will use to write the page
// if not released this will leak...

// the method continues...

// at the end I have

CGContextEndPage (pdfContext);
CGPDFContextClose(pdfContext);
CGContextRelease (pdfContext);

Xcode抱怨最后一行。如果我包含它,则表示调用者此时不拥有的对象的引用计数的不正确减少

如果我删除该行,则说明:在第X行分配的对象的潜在泄漏其中X是创建上下文的行...

如果我在createPDFContext方法上释放上下文,它会崩溃!

这里有createPDF方法

-(CGContextRef) createPDFContext:(CGRect)inMediaBox path:(CFStringRef) path
{
    CGContextRef myOutContext = NULL;
    CFURLRef url;
    CGDataConsumerRef dataConsumer;

    url = CFURLCreateWithFileSystemPath (NULL,  path, kCFURLPOSIXPathStyle, false);

    if (url != NULL)
    {
        dataConsumer = CGDataConsumerCreateWithURL (url);
        if (dataConsumer != NULL)
        {
            myOutContext = CGPDFContextCreate (dataConsumer, &inMediaBox, NULL);
            CGDataConsumerRelease (dataConsumer);
        }
        CFRelease(url);
    }

//  CGContextRelease(myOutContext);
    return myOutContext;
}

如何解决?

1 个答案:

答案 0 :(得分:2)

鉴于Cocoa内存管理规则,您的方法createPDFContext:path:不应返回调用者拥有的对象。规则要求方法包含“new”,“copy”,“alloc”和“mutableCopy”以返回调用者拥有的对象。您的方法返回带有+1保留计数的CGContextRef。因此,您在释放此方法返回的对象时是正确的,但是,由于您的命名约定违反规则,分析器会抱怨它。

您不应该在createPDFContext:path中释放上下文:因为这会阻止您使用它。

您可以通过重命名方法或使其成为C函数来解决此问题。 C函数将遵循Core Foundation内存管理规则,该规则期望函数名称中包含“create”或“copy”,以返回调用者拥有的对象。