我在尝试绘制路径时发现,在至少某些情况下,UIBezierPath的性能优于我原本认为与之等效的Core Graphics。下面的-drawRect:
方法创建了两个路径:一个是UIBezierPath,另一个是CGPath。这两个路径除了位置不同以外完全相同,但描边CGPath要花费大约两倍的时间比描边UIBezierPath。
- (void)drawRect:(CGRect)rect
{
CGContextRef ctx = UIGraphicsGetCurrentContext();
// Create the two paths, cgpath and uipath.
CGMutablePathRef cgpath = CGPathCreateMutable();
CGPathMoveToPoint(cgpath, NULL, 0, 100);
UIBezierPath *uipath = [[UIBezierPath alloc] init];
[uipath moveToPoint:CGPointMake(0, 200)];
// Add 200 curve segments to each path.
int iterations = 200;
CGFloat cgBaseline = 100;
CGFloat uiBaseline = 200;
CGFloat xincrement = self.bounds.size.width / iterations;
for (CGFloat x1 = 0, x2 = xincrement;
x2 < self.bounds.size.width;
x1 = x2, x2 += xincrement)
{
CGPathAddCurveToPoint(cgpath, NULL, x1, cgBaseline-50, x2, cgBaseline+50, x2, cgBaseline);
[uipath addCurveToPoint:CGPointMake(x2, uiBaseline)
controlPoint1:CGPointMake(x1, uiBaseline-50)
controlPoint2:CGPointMake(x2, uiBaseline+50)];
}
[[UIColor blackColor] setStroke];
CGContextAddPath(ctx, cgpath);
// Stroke each path.
[self strokeContext:ctx];
[self strokeUIBezierPath:uipath];
[uipath release];
CGPathRelease(cgpath);
}
- (void)strokeContext:(CGContextRef)context
{
CGContextStrokePath(context);
}
- (void)strokeUIBezierPath:(UIBezierPath*)path
{
[path stroke];
}
两个路径都使用了CGContextStrokePath()函数,因此我创建了单独的方法来描绘每个路径,以便我可以在Instruments中查看每个路径所用的时间。以下是典型结果(调用树倒置); 您可以看到-strokeContext:
需要9.5秒,而-strokeUIBezierPath:
仅需要5秒。
Running (Self) Symbol Name
14638.0ms 88.2% CGContextStrokePath
9587.0ms 57.8% -[QuartzTestView strokeContext:]
5051.0ms 30.4% -[UIBezierPath stroke]
5051.0ms 30.4% -[QuartzTestView strokeUIBezierPath:]
看起来UIBezierPath以某种方式优化了它创建的路径,或者我用一种天真的方式创建了CGPath。我该怎么做才能加快我的CGPath绘制速度?
UIBezierPath
是对CGPathRef
的封装。如果你运行这两个的代码,比如说一千万次,然后取平均值,但不使用 Instruments 工具,而是用两个NSDate
对象记录操作前后的时间。 - user142019-drawRect:
被调用几十次还是几百次都不会改变。我已经在模拟器上尝试了多达 80000 条曲线段(对于设备来说太多了)。结果总是差不多:CGPath 的时间大约是 UIBezierPath 的两倍,尽管两者都使用 CGContextStrokePath() 进行绘制。很明显,UIBezierPath 构造的路径比我使用 CGPathAddCurveToPoint() 创建的路径更有效率。我想知道如何像 UIBezierPath 一样构建高效的路径。 - Caleb