Drawing a grid in UIScrollView#39;s subview allocates huge memory(在 UIScrollView 的子视图中绘制网格会分配巨大的内存)
问题描述
我正在尝试在 UIScrollView 中创建一个 UIView,它只包含一个简单的网格(行和列),由 UIBezierPath 或使用 CG 函数淹没.问题是,当我有较大的 UIScrollView 内容大小(以及较大的子视图)时,在绘制网格期间分配了大量内存(50MB 或更多).
I'm trying to create a UIView in UIScrollView that contains just a simple grid (lines as rows and columns) drown by UIBezierPath or using the CG functions. The problem is, that when I have larger content size of the UIScrollView (as well as the larger subview), during the drawing of the grid huge amount of memory is allocated (50MB or more).
UIViewController 仅包含整个场景的 UIScrollView - 在 viewDidLoad 中添加子视图:
UIViewController which includes just UIScrollView over whole scene - adding subview in 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(网格中一个单元格的宽度/高度):
Inner view that just draw the grid using UIBezierPath/CG functions - depends on properties size(rows/columns count) and cellSize (width/height of one cell in grid):
#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 为 2000x2000 点以及内部视图的框架 => 18 行被淹没,它分配了 ~60MB 内存
Example1: self.size is 10, self.cellSize is 200 => contentSize is 2000x2000 points as well as frame of inner view => 18 lines are drown and it allocates ~60MB memory
示例 2:self.size 为 30,self.cellSize 为 70 => contentSize 为 2100x2100 点以及内部视图框架 => 58 行被淹没,它分配了 ~67MB 内存
Example2: self.size is 30, self.cellSize is 70 => contentSize is 2100x2100 points as well as frame of inner view => 58 lines are drown and it allocates ~67MB memory
我在调试绘图方法时可以看到这些内存编号.无论我如何画线,调用 [path stroke] 时都会分配大量内存.CGContextStrokePath(上下文).在仪器中,我可以看到最大的内存分配:
These memory numbers I can see when debug the drawing method. No matter how I draw the lines, huge amount of memory is allocated when calling [path stroke] resp. CGContextStrokePath(context). In instruments I can see the biggest memory allocation at line:
12658 0x10200000 VM:CoreAnimation 00:04.092.149 • 67,29 MB QuartzCore CA::Render::Shmem::new_shmem(unsigned long)
12658 0x10200000 VM: CoreAnimation 00:04.092.149 • 67,29 MB QuartzCore CA::Render::Shmem::new_shmem(unsigned long)
我是 iOS 编程的新手,我到处寻找解决方案,但我仍然不知道 :-/谁能帮我找到一些解释这里发生了什么?谢谢:)
I'm quite new in iOS programming and I was searching the solution everywhere and I still have no idea :-/ Can anyone please help me find some explanation what is going on here? Thanks :)
推荐答案
在苹果开发者论坛上询问后发现,这实际上是正确分配的内存.这是因为任何使用 -drawRect: 进行绘制的视图都会使用 (bounds.size.width * bounds.size.height * contentScale * contentScale * 4) 字节的内存.
After asking on apple developer forum, I find out, that this is properly allocated memory in fact. It's because any view that uses -drawRect: to draw will use memory on the order of (bounds.size.width * bounds.size.height * contentScale * contentScale * 4) bytes.
创建避免这种情况的网格的最简单方法是使用为每一行添加一个视图并使用视图的 backgroundColor 属性为视图着色.这几乎不会占用任何内存,因为视图(可以是普通的 UIView)不需要调用 -drawRect:,因此不会使用额外的内存来存储绘图结果.
The simplest way to create a grid that avoids that is to use add a view for each line and use the view's backgroundColor property to color the view. This will use hardly any memory because the view's (which can be plain UIViews) don't need to call -drawRect:, and thus won't use extra memory to store the results of your drawing.
这篇关于在 UIScrollView 的子视图中绘制网格会分配巨大的内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:在 UIScrollView 的子视图中绘制网格会分配巨大的内
基础教程推荐
- 如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar? 2022-01-01
- 当从同一个组件调用时,两个 IBAction 触发的顺序是什么? 2022-01-01
- UIWebView 委托方法 shouldStartLoadWithRequest:在 WKWebView 中等效? 2022-01-01
- android 应用程序已发布,但在 google play 中找不到 2022-01-01
- 在 gmail 中为 ios 应用程序检索朋友的朋友 2022-01-01
- 如何在 UIImageView 中异步加载图像? 2022-01-01
- 如何让对象对 Cocos2D 中的触摸做出反应? 2022-01-01
- Android:对话框关闭而不调用关闭 2022-01-01
- Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m “kivy"d 2022-01-01
- 如何在 iPhone 上显示来自 API 的 HTML 文本? 2022-01-01