我有一种在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;
}
如何解决?
答案 0 :(得分:2)
鉴于Cocoa内存管理规则,您的方法createPDFContext:path:不应返回调用者拥有的对象。规则要求方法包含“new”,“copy”,“alloc”和“mutableCopy”以返回调用者拥有的对象。您的方法返回带有+1保留计数的CGContextRef。因此,您在释放此方法返回的对象时是正确的,但是,由于您的命名约定违反规则,分析器会抱怨它。
您不应该在createPDFContext:path中释放上下文:因为这会阻止您使用它。
您可以通过重命名方法或使其成为C函数来解决此问题。 C函数将遵循Core Foundation内存管理规则,该规则期望函数名称中包含“create”或“copy”,以返回调用者拥有的对象。