我每隔0.1秒使用NSTimer从网格中绘制单元格。 大小约为96x64 => 6144个细胞/图像。 如果我正在绘制图像而不是(例如)绿色矩形,它会慢4倍!
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
UIGraphicsPushContext(context);
CGContextSetRGBFillColor(context, 0, 0, 0, 1);
CGContextFillRect(context, CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height));
int cellSize = self.bounds.size.width / WIDTH;
double xOffset = 0;
for (int i = 0; i < WIDTH;i++)
{
for (int j = 0; j < HEIGHT;j++)
{
NSNumber *currentCell = [self.state.board objectAtIndex:(i*HEIGHT)+j];
if (currentCell.intValue == 1)
{
[image1 drawAtPoint:CGPointMake(xOffset + (cellSize * i),cellSize * j )];
}
else if (currentCell.intValue == 0){
[image2 drawAtPoint:CGPointMake(xOffset + (cellSize * i),cellSize * j )];
}
}
}
UIGraphicsPopContext();
}
如果我想在每个矩形中绘制png或jpg,任何想法如何更快? 图像已经缩放到适当的大小。
答案 0 :(得分:3)
a)不要重绘视图边界之外的图像/视频。
b)不要重绘dirtyRect之外的图像/作品
c)不要重绘自此以来没有变化的图像/作品 之前的更新。
d)使用图层预呈现图像,因此您无需渲染 他们在抽奖时间。
答案 1 :(得分:2)
这种情况正是仪器所针对的。用它。这里提出建议的任何人都在猜测瓶颈是什么。
那就是说,我要猜测瓶颈是什么。您正在使用CPU绘制6114个图像(使用时间分析器确认这一点。找到您的drawRect方法,并检查花费的时间最多。如果是drawInRect,那那就是您的问题)
如果是这种情况,我们如何减少其使用量?一个简单的胜利就是只重绘我们需要绘制的图像。 CALayers让这很容易。删除drawRect方法,为每个图像的视图层添加子图层,并将图像设置为图层的内容属性。无需在图像需要更改时使视图无效,只需将相关图层的内容属性切换为新图像。
关于CALayers的另一个好处是它们可以在GPU上缓存图层内容,这意味着发生的重绘会占用更少的CPU时间,并且当它们发生时不会阻止其余的应用程序。
如果那么多层的开销是不可接受的(再次,Instruments是你的朋友),请查看CAReplicatorLayer。它不如拥有许多CALayers灵活,但允许以最小的开销多次复制单个图像。
答案 2 :(得分:1)
我尝试从性能角度改进您的代码。但是,请检查我对瓶颈的评论。
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
//UIGraphicsPushContext(context); //not needed UIView does it anyway
//use [UIView backgroundColor] instead of this
//CGContextSetRGBFillColor(context, 0, 0, 0, 1);
//CGContextFillRect(context, CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height));
int cellSize = self.bounds.size.width / WIDTH;
double xOffset = 0;
CGRect cellFrame = CGRectMake(0, 0, cellSize, cellSize);
NSUinteger cellIndex = 0;
for (int i = 0; i < WIDTH; i++) {
cellFrame.origin.x = xOffset;
for (int j = 0; j < HEIGHT; j++, cellIndex++) {
cellFrame.origin.y = 0;
if (CGRectIntersectsRect(rect, cellFrame) {
NSNumber *currentCell = [self.state.board objectAtIndex:cellIndex];
if (currentCell.intValue == 1) {
[image1 drawInRect:cellFrame];
}
else if (currentCell.intValue == 0) {
[image2 drawInRect:cellFrame];
}
}
cellFrame.origin.y += cellSize;
}
cellFrame.origin.x += cellSize;
}
//UIGraphicsPopContext(context); //not needed UIView does it anyway
}
答案 3 :(得分:0)
使用CGRectIntersects
检查图像的矩形是否在dirtyRect内,以检查是否需要绘制它。