問(wèn)題描述
我正在嘗試在 UIScrollView 中創(chuàng)建一個(gè) UIView,它只包含一個(gè)簡(jiǎn)單的網(wǎng)格(行和列),由 UIBezierPath 或使用 CG 函數(shù)淹沒(méi).問(wèn)題是,當(dāng)我有較大的 UIScrollView 內(nèi)容大小(以及較大的子視圖)時(shí),在繪制網(wǎng)格期間分配了大量?jī)?nèi)存(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 僅包含整個(gè)場(chǎng)景的 UIScrollView - 在 vi??ewDidLoad 中添加子視圖:
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 函數(shù)繪制網(wǎng)格的內(nèi)部視圖 - 取決于屬性大小(行數(shù)/列數(shù))和 cellSize(網(wǎng)格中一個(gè)單元格的寬度/高度):
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 點(diǎn)以及內(nèi)部視圖的框架 => 18 行被淹沒(méi),它分配了 ~60MB 內(nèi)存
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 點(diǎn)以及內(nèi)部視圖框架 => 58 行被淹沒(méi),它分配了 ~67MB 內(nèi)存
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
我在調(diào)試?yán)L圖方法時(shí)可以看到這些內(nèi)存編號(hào).無(wú)論我如何畫線,調(diào)用 [path stroke] 時(shí)都會(huì)分配大量?jī)?nèi)存.CGContextStrokePath(上下文).在儀器中,我可以看到最大的內(nèi)存分配:
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 編程的新手,我到處尋找解決方案,但我仍然不知道 :-/誰(shuí)能幫我找到一些解釋這里發(fā)生了什么?謝謝:)
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 :)
推薦答案
在蘋果開(kāi)發(fā)者論壇上詢問(wèn)后發(fā)現(xiàn),這實(shí)際上是正確分配的內(nèi)存.這是因?yàn)槿魏问褂?-drawRect: 進(jìn)行繪制的視圖都會(huì)使用 (bounds.size.width * bounds.size.height * contentScale * contentScale * 4) 字節(jié)的內(nèi)存.
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.
創(chuàng)建避免這種情況的網(wǎng)格的最簡(jiǎn)單方法是使用為每一行添加一個(gè)視圖并使用視圖的 backgroundColor 屬性為視圖著色.這幾乎不會(huì)占用任何內(nèi)存,因?yàn)橐晥D(可以是普通的 UIView)不需要調(diào)用 -drawRect:,因此不會(huì)使用額外的內(nèi)存來(lái)存儲(chǔ)繪圖結(jié)果.
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.
這篇關(guān)于在 UIScrollView 的子視圖中繪制網(wǎng)格會(huì)分配巨大的內(nèi)存的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!