在UIScrollView的子视图中绘制一个网格分配巨大的内存

我试图在UIScrollView中创build一个UIView,其中只包含一个由UIBezierPath或使用CG函数淹没的简单网格(行为行和列)。 问题是,当我有更大的内容大小的UIScrollView(以及更大的子视图),在绘制网格时,分配了大量的内存(50MB或更多)。

UIViewController其中包括整个场景只是UIScrollView – 在viewDidLoad中添加子视图:

@interface TTTTestViewController() @property (weak, nonatomic) IBOutlet UIScrollView *scrollView; @end @implementation TTTTestViewController -(void)viewDidLoad { [super viewDidLoad]; // create the subview TTTTestView *testView = [[TTTTestView alloc] init]; [self.scrollView addSubview:testView]; //set its properties testView.cellSize = 50; testView.size = 40; // set the content size and frame of testView by the properties self.scrollView.contentSize = CGSizeMake(testView.cellSize * testView.size, testView.cellSize * testView.size); testView.frame = CGRectMake(0, 0, self.scrollView.contentSize.width, self.scrollView.contentSize.height); // let it draw the grid [testView setNeedsDisplay]; } @end 

使用UIBezierPath / CG函数绘制网格的内部视图取决于属性大小(行/列数)和cellSize(网格中一个单元格的宽度/高度):

 #define GRID_STROKE_WIDTH 2.0 @implementation TTTTestView - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.backgroundColor = [UIColor clearColor]; } return self; } - (void)drawRect:(CGRect)rect { [super drawRect:rect]; [self drawGrid]; } -(void)drawGrid { UIBezierPath *path = [[UIBezierPath alloc] init]; for (int i = 1; i < self.size; i++) { //draw row line [path moveToPoint:CGPointMake(0, self.cellSize * i)]; [path addLineToPoint:CGPointMake(self.bounds.size.width, self.cellSize * i)]; // draw column line [path moveToPoint:CGPointMake(self.cellSize * i, 0)]; [path addLineToPoint:CGPointMake(self.cellSize * i , self.bounds.size.height)]; } [path setLineWidth:GRID_STROKE_WIDTH]; [[UIColor blackColor] setStroke]; [path stroke]; /* CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetLineWidth(context, GRID_STROKE_WIDTH); CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor); for (int i = 1; i < self.size; i++) { //draw row line CGContextMoveToPoint(context, 0, self.cellSize * i ); CGContextAddLineToPoint(context, self.bounds.size.width, self.cellSize * i); // draw column line CGContextMoveToPoint(context, self.cellSize * i , 0); CGContextAddLineToPoint(context, self.cellSize * i , self.bounds.size.height); } CGContextStrokePath(context); */ } @end 

示例1:self.size为10,self.cellSize为200 => contentSize为2000×2000点以及内部视图的框架=> 18行被淹没,并分配〜60MB的内存

例2:self.size是30,self.cellSize是70 => contentSize是2100×2100点以及内部视图的框架=> 58行被淹没,它分配〜67MB内存

debugging绘图方法时可以看到的这些内存编号。 无论如何画线,调用[path stroke] resp时都会分配大量的内存。 CGContextStrokePath(上下文)。 在仪器中,我可以看到最大的内存分配:

12658 0x10200000 VM:CoreAnimation 00:04.092.149•67,29 MB QuartzCore CA :: Render :: Shmem :: new_shmem(unsigned long)

我在iOS编程方面很新,我到处寻找解决scheme,但我仍然不知道: – /任何人都可以请帮我find一些解释发生了什么? 谢谢 :)

在问苹果开发者论坛之后,我发现,这实际上是正确分配内存。 这是因为使用-drawRect:绘制的任何视图将按照(bounds.size.width * bounds.size.height * contentScale * contentScale * 4)字节的顺序使用内存。

创build网格的最简单的方法是避免使用为每行添加视图并使用视图的backgroundColor属性为视图着色。 这将几乎不使用任何内存,因为视图(可以是普通的UIViews)不需要调用-drawRect :,因此不会使用额外的内存来存储绘图的结果。