我正在使用ARC制作基于网格的应用。基本上屏幕中央有一个4x4-8x8网格(占据屏幕的大部分)。这个网格是使用一个UIView构建的,它用一些颜色和用drawRect:
绘制的线条着色(我将在下面张贴所有相关代码以供参考)。
对于包含在行的另一个NSMutableArray中的每一行,每个单元格都包含在NSMutableArray中:
在每个单元格中,我有一个actor对象或占位符对象。占位符对象本质上只是一个空白的NSObject,而actor对象有8个基本属性和1个对象属性。
例如,其中一个actor是一个源,它基本上递归地从源中跨越网格绘制一个普通的UIView,直到它击中另一个actor或网格的墙。
蓝色和红色线条显示当前正在运行的不同UIViews。网格这么小,记忆似乎不是常见问题;然而,当完整游戏以8x8网格运行时,除了作为源,动作等的UIImageViews以及不包括的其他UILabel和按钮之外,屏幕上还可以有50多个绘制的UIViews。在网格中。屏幕上可以同时轻松显示超过100个UIViews,即使在具有最佳硬件的最新设备上,也会导致一些非常糟糕的延迟。
我觉得这与我一次向屏幕呈现100多个视图这一事实有关。
我可以将所有这些动态绘制的线条合并到一个视图中,还是完全有更好的解决方案?
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
CGContextRef context = UIGraphicsGetCurrentContext();
CGColorRef color = [[self backgroundColor] CGColor];
int numComponents = CGColorGetNumberOfComponents(color);
CGFloat red = 0, green = 0, blue = 0;
if (numComponents == 4)
{
const CGFloat *components = CGColorGetComponents(color);
red = components[0];
green = components[1];
blue = components[2];
}
CGContextSetRGBFillColor(context, red, green, blue, 0.5);
float top;
float cell = [self cellWidth];
float grid = [self gridWidth];
//Draw
for(int i = 0; i < [self size]+1; i++)
{
top = i*(cell+lineWidth);
CGContextFillRect(context, CGRectMake(0, top, grid, lineWidth));
CGContextFillRect(context, CGRectMake(top, 0, lineWidth, grid));
}
}
- (void)addSources:(NSArray*)sources
{
for(int i = 0; i < [sources count]; i++)
{
NSArray* src = [sources objectAtIndex:i];
int row = [[src objectAtIndex:1] intValue];
int column = [[src objectAtIndex:0] intValue];
int direction = [[src objectAtIndex:2] intValue];
int color = [UIColor colorKeyForString:[src objectAtIndex:3]];
float width = [self cellWidth]*scaleActors;
float x = lineWidth + (([self cellWidth]+lineWidth) * (column-1)) + (([self cellWidth]-width)/2.0);
float y = lineWidth + (([self cellWidth]+lineWidth) * (row-1)) + (([self cellWidth]-width)/2.0);
ActorView* actor = [[ActorView alloc] initWithFrame:CGRectMake(x, y, width, width)];
[actor setType:4];
[actor setDirection:direction];
[actor setColorKey:color];
[actor setIsGlowing:YES];
[actor setPicture];
if([self isCreatingLevel])
[actor setCanRotate:YES];
[self addSubview:actor];
[[[self rows] objectAtIndex:(row-1)] replaceObjectAtIndex:(column-1) withObject:actor];
}
}
到目前为止,我在屏幕上有大约48个绘制的视图(总共约70个视图)。
答案 0 :(得分:1)
我建议使用WWDC 2012视频iOS App Performance: Responsiveness作为使用Instruments追踪这些问题的良好入门书。该视频中有很多好的技巧和提示。
但我同意这些观点看起来并不古怪(尽管我可能很想在CoreGraphics中渲染这一点)。我没有使用相同的模型,但这是一个纯图形渲染的图形,只有一个UIView
子类:
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
// configure the gridlines
CGContextSetStrokeColorWithColor(context, [[UIColor blackColor] CGColor]);
CGContextSetLineWidth(context, 8.0);
CGContextSetLineCap(context, kCGLineCapSquare);
// add the horizontal gridlines
for (NSInteger row = 0; row <= self.rows; row++)
{
CGPoint from = [self coordinateForX:0 Y:row];
CGPoint to = [self coordinateForX:_cols Y:row];
CGContextMoveToPoint(context, from.x, from.y);
CGContextAddLineToPoint(context, to.x, to.y);
}
// add the vertical gridlines
for (NSInteger col = 0; col <= self.cols; col++)
{
CGPoint from = [self coordinateForX:col Y:0 ];
CGPoint to = [self coordinateForX:col Y:_rows];
CGContextMoveToPoint(context, from.x, from.y);
CGContextAddLineToPoint(context, to.x, to.y);
}
// stroke the gridlines
CGContextStrokePath(context);
// now configure the red/blue line segments
CGContextSetLineWidth(context, self.bounds.size.width / _cols / 2.0);
CGContextSetLineCap(context, kCGLineCapRound);
// iterate through our array of points
CGPoint lastPoint = [self.points[0] CGPointValue];
for (NSInteger i = 1; i < [self.points count]; i++)
{
// set the color
if (i % 2)
CGContextSetStrokeColorWithColor(context, [[UIColor redColor] CGColor]);
else
CGContextSetStrokeColorWithColor(context, [[UIColor blueColor] CGColor]);
CGPoint nextPoint = [self.points[i] CGPointValue];
// create path
CGPoint from = [self coordinateForCenterX:lastPoint.x Y:lastPoint.y];
CGPoint to = [self coordinateForCenterX:nextPoint.x Y:nextPoint.y];
CGContextMoveToPoint(context, from.x, from.y);
CGContextAddLineToPoint(context, to.x, to.y);
// stroke it
CGContextStrokePath(context);
// save the last point
lastPoint = nextPoint;
}
}
现在,也许你正在做其他需要更复杂处理的事情,在这种情况下,WWDC视频(或者,iOS App Performance: Graphics and Animations)应该指向正确的方向。