【发布时间】:2011-02-19 11:50:14
【问题描述】:
这个问题是关于 UIView 的 -drawRect 函数的。
设置:
我的应用程序包含多页 PDF 文档,可以通过启用分页的 ScrollView 进行翻阅。每个页面 (PDFDisplayView) 都是一个 UIView 自定义使用 Core Graphics CGPDF 功能来绘制 PDF 文档的特定页面。滚动视图尝试通过加载视图中的页面并卸载未使用的页面来优化内存。加载页面会初始化一个 UIViewController,它将其视图 (PDFDisplayView) 添加到 ScrollView,这会调用 PDFDisplayView 的 -drawRect 函数(如下所示)。
谜团:
将视图 (PDFDisplayView) 添加到其父视图 (ScrollView) 会调用 -drawRect 函数,并且在 Instruments Object Allocations 可视化工具中,内存大小会增加。神秘之处在于,尽管 -drawRect 似乎增加了内存使用量,但在卸载时从超级视图 (ScrollView) 中删除视图似乎并没有减少内存使用量,因为可视化图表一直在上升,而不是下降。结果是,随着您使用应用程序,内存使用量继续扩大,这会导致内存警告并最终崩溃...
其他信息:
我检查了代码的所有其他方面,以确保我没有在其他地方泄漏内存——一切看起来都很好。这让我怀疑 drawRect 是罪魁祸首。我已经包含了下面的代码。请告诉我你的想法。谢谢。
- (void)drawRect:(CGRect)rect {
CGPDFPageRef thePageRef = [[PDFReaderAppDelegate sharedAppDelegate] getPageRefForPage:self.currentPage];
if(thePageRef)
{
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSaveGState(ctx);
CGContextTranslateCTM(ctx, 0.0, [self bounds].size.height);
CGContextScaleCTM(ctx, 1.0, -1.0);
CGContextConcatCTM(ctx,
CGPDFPageGetDrawingTransform(thePageRef, kCGPDFCropBox,
[self bounds], 0, true));
CGContextDrawPDFPage(ctx, thePageRef);
CGContextRestoreGState(ctx);
NSLog(@"Drew PDFDisplayView of page %i (-drawRect)", self.currentPage);
}
}
【问题讨论】:
-
我怀疑问题出在 appDelegate 中。每次你请求一个页面时,你说它加载到内存中。你在哪里发布那个页面?我假设对页面的请求会加载它,对页面的请求是否也会释放所有其他页面?
-
@Hiltmon 感谢您的评论。 UIViewController 对象(代表页面)存储在一个数组中。每个都在卸载时替换为 NSNull 对象。此外,此时每个视图控制器的 PDFDisplayView (UIView) 从其父视图 (ScrollView) 中删除。我的理解是这应该释放所有资源......因此是个谜......
-
嗯,这让我很困惑。页面应该是模型对象,并在不再需要时释放(而不是替换)。从其父视图中删除一个对象只会导致它在retaincount为1时被释放。检查一下。可能还有另一个指向它的指针。检查是否调用了 dealloc 方法。再测试一个,为什么不复用Page UIView,只替换它显示的页面,不添加,不删除,没有内存问题。
-
@Hiltmon 非常有趣的观点......谢谢!我会调查的。
标签: objective-c xcode ios core-graphics drawrect