iOS 8.1中CGContextDrawPDFPage存在内存泄漏问题?

5

在iOS 8.1上,使用CGContextDrawPDFPage将PDF页面渲染到图形上下文时会出现内存泄漏。在模拟器中不会发生,但每次在iPad Air上进行此操作时都会有数百个272字节的malloc'd内存泄漏。如果注释掉CGContextDrawPDFPage,则内存泄漏消失。

是否有其他人遇到类似问题?

CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData((CFDataRef)data);
CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(dataProvider);


CGPDFPageRef page;

// Grab the PDF page
page = CGPDFDocumentGetPage(pdf, pageNo + 1);

UIGraphicsBeginImageContext(aRect.size);
CGContextRef context = UIGraphicsGetCurrentContext();

CGContextTranslateCTM(context, 0, aRect.size.height);
CGContextScaleCTM(context, 1, -1);

CGContextDrawPDFPage(context, page); // <-  LEAKING?!?!?

// Would create the new UIImage from the context
//image = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

CGPDFDocumentRelease(pdf);
CGDataProviderRelease(dataProvider);

以下是逆序的堆栈追踪:

malloc

std::__1::list >::list(std::__1::list > const&),使用了 38.58 MB,占比 36.7%,出现次数 148743

std::__1::vector CG::Path::Subpath CG::Allocator,使用了 19.61 MB,占比 18.6%,出现次数 75610

void std::__1::vector >::__push_back_slow_path(CG::Path::Subpath&&),使用了 19.61 MB,占比 18.6%,出现次数 75610

CG::Path::Sequence::move_to_point(CGPoint const&, CGAffineTransform const*),使用了 19.61 MB,占比 18.6%,出现次数 75610

CGPathMoveToPoint,使用了 19.61 MB,占比 18.6%,出现次数 75610

TTrueTypeQuadOutlineContext::AddPoint(bool, int, int),使用了 19.59 MB,占比 18.6%,出现次数 75506

TTrueTypeFontHandler::RenderGlyph(unsigned short, TTrueTypeQuadOutlineContext&, unsigned int) const,使用了 19.59 MB,占比 18.6%,出现次数 75506

TTrueTypeFontHandler::GetOutlinePath(unsigned short, TGlyphOutlineBatch const&) const,使用了 19.59 MB,占比 18.6%,出现次数 75506

FPFontCopyGlyphPath,使用了 19.59 MB,占比 18.6%,出现次数 75506

CGFontCreateGlyphPath,使用了 19.59 MB,占比 18.6%,出现次数 75506

CGFontCreateGlyphBitmap,使用了 19.59 MB,占比 18.6%,出现次数 75506

CGGlyphBuilder::create_missing_bitmaps(CGGlyphIdentifier const*, unsigned long, CGGlyphBitmap const**),使用了 19.59 MB,占比 18.6%,出现次数 75506

render_glyphs,使用了 19.59 MB,占比 18.6%,出现次数 75506

draw_glyph_bitmaps,使用了 19.59 MB,占比 18.6%,出现次数 75506

ripc_DrawGlyphs,使用了 19.59 MB,占比 18.6%,出现次数 75506

draw_glyphs,使用了 19.59 MB,占比 18.6%,出现次数 75506

draw_glyphs,使用了 19.57 MB,占比 18.6%,出现次数 75434

simple_draw,使用了 19.55 MB,占比 18.6%,出现次数 75359

CGPDFTextLayoutDrawGlyphs,使用了 19.55 MB,占比 18.6%,出现次数 75359

op_TJ,使用了 19.55 MB,占比 18.6%,出现次数 75348

pdf_scanner_handle_xname,使用了 19.55 MB,占比 18.6%,出现次数 75348

CGPDFScannerScan,使用了 19.55 MB,占比 18.6%,出现次数 75348

CGPDFDrawingContextDrawPage,使用了 19.55 MB,占比 18.6%,出现次数 75348

19.55 MB 18.6% 75348

这里涉及到PDF页面绘制技术。其中“pdf_page_draw_in_context”和“CGContextDrawPDFPage”都是用于在上下文中绘制PDF页面的函数名称。


您在此问题上使用了ios8标签,并在标题中提到了8.1。您能否请澄清一下?该问题是iOS 8.1新出现的,还是在8.0中也存在? - Jeremy Huddleston Sequoia
另外,你是否在自动释放池中运行此代码?为了确保不是延迟释放的问题,请尝试在此代码周围添加@autoreleasepool {}(请注意,这显然会释放你最终想要传递的“image”,但至少可以排除这种可能性)。 - Jeremy Huddleston Sequoia
我认为这也发生在8.0版本中。我尝试过使用自动释放块进行包装,但没有成功。我刚刚得到了一个内存泄漏的堆栈跟踪。我会更新问题。 - Paul Phoenix
1个回答

0

是的,您需要调用UIGraphicsEndImageContext()来匹配每个对UIGraphicsBeginImageContext()的调用。

根据UIKit框架参考

当您完成修改上下文时,必须调用UIGraphicsEndImageContext函数来清理位图绘制环境并从上下文堆栈中删除图形上下文。您不应使用UIGraphicsPopContext函数从堆栈中删除此类型的上下文。


1
已经在那里了。我已经调用过它来修复漏洞。但它仍在泄漏! - Paul Phoenix
是的,我能看到它在那里,并且有一个注释表明它修复了泄漏。我已经在上面添加了一个解释,说明为什么需要它。从你的评论中,似乎我误解了你在代码中的评论。我将编辑你的问题,删除误导性的“// fix leak”。 - Jeremy Huddleston Sequoia
谢谢。对不起没有说清楚。现有的内存泄漏非常奇怪。调用该函数100次会泄漏很多。在分析器中非常明显! - Paul Phoenix
@PaulPhoenix 你找到解决方案了吗? - Ahmed Khalaf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接