我正在开发的应用程序相对简单,但它会引发内存警告。我试图弄清楚应用程序设计是否需要太多内存,应该重新设计和分解以减少使用,或者应用程序设计很好,但应用程序本身臃肿并且错误地吞噬了比需要更多的内存。
该应用程序从 Web 下载一个包含一组问题的 XML 文件,然后生成一个 UIScrollView 来显示问题控件列表。每个问题控件都有一个 UITextView 和一个 UISegmentedControl、UIButton、UITableView、UITextField 或四个带有 UIButton(自定义日期控件)的 UITextField。这是一个屏幕截图:
此设置适用于较小的问题集,但该应用程序开始抛出超过 120 个问题的较大集的内存警告。这是在更大的集合上使用 Allocations 和 VM Tracker Instruments 的典型运行:
xml 下载和模型加载时的分配内存峰值,但直到分配内存达到稳定状态后才会引发警告。VM Tracker 内存在它们被抛出时仍在增加,这让我认为控件仍在加载到内存中,并且 VM Tracker 是内存增长导致警告的更好指标。当驻留大小大于 125 MB 时,通常会出现警告。我找到了一种方法可以显着降低 Resident 的大小。问题控件有一个自定义视图,可以为它们提供圆角边缘和阴影。如果我从自定义视图中注释掉 drawRect 代码(如下所示),分配内存保持不变,但驻留大小下降约 30 MB,并且不会增长到 93 MB 以上。
- (void)drawRect:(CGRect)rect {
// get the contect
CGContextRef context = UIGraphicsGetCurrentContext();
//for the shadow, save the state then draw the shadow
CGContextSaveGState(context);
CGContextSetShadow(context, CGSizeMake(4,-5), 10);
//now draw the rounded rectangle
CGContextSetStrokeColorWithColor(context, [[UIColor blackColor] CGColor]);
if(_HighlightColor==nil){
_HighlightColor = [[UIColor whiteColor] retain];
}
CGContextSetFillColorWithColor(context, _HighlightColor.CGColor);
//since I need room in my rect for the shadow, make the rounded rectangle a little smaller than frame
CGRect rrect = CGRectMake(CGRectGetMinX(rect), CGRectGetMinY(rect), CGRectGetWidth(rect)-30, CGRectGetHeight(rect)-30);
CGFloat radius = 5;
// the rest is pretty much copied from Apples example
CGFloat minx = CGRectGetMinX(rrect), midx = CGRectGetMidX(rrect), maxx = CGRectGetMaxX(rrect);
CGFloat miny = CGRectGetMinY(rrect), midy = CGRectGetMidY(rrect), maxy = CGRectGetMaxY(rrect);
// Start at 1
CGContextMoveToPoint(context, minx, midy);
// Add an arc through 2 to 3
CGContextAddArcToPoint(context, minx, miny, midx, miny, radius);
// Add an arc through 4 to 5
CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius);
// Add an arc through 6 to 7
CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius);
// Add an arc through 8 to 9
CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius);
// Close the path
CGContextClosePath(context);
// Fill & stroke the path
CGContextDrawPath(context, kCGPathFillStroke);
//for the shadow
CGContextRestoreGState(context);
}
仪器和内存警告看起来像是内存已用尽,但这些数字对我来说似乎很高。我不认为滚动视图中的 120 个问题控件对 iPad 来说是个问题,但我没有关于它们应该使用多少内存的参考框架。考虑到 iPad 可以运行的一些图形密集型游戏,上面的简单 drawRect 代码似乎不会在问题控件中占用超过 30 MB 的空间。这种内存使用率是否看起来很高,或者这是否是您对具有这么多简单 UI 元素的应用程序的期望?drawRect 中是否有一些东西会占用大量内存或有关如何优化它的任何建议?如果看起来这应该最大化 iPad 的内存,我将创建选项卡或页面,并限制我放在选项卡/页面上的问题数量,以便一次仅将一小部分控件加载到内存中。但是,如果 iPad 应该能够在内存中处理它们,我宁愿不分解它们。非常感谢任何输入。