drawRect:缩放后大直立崩溃

时间:2012-10-26 12:18:48

标签: objective-c quartz-core

我的UIView结构: 我有一个"master" UIView(实际上UIScrollView,但它的目的只是滚动每个分页)。 作为此"master"上的子视图,我有"pageView"UIScrollView的子类)。此UIScrollView可以包含任何内容(例如UIImageView)。 "master"有另一个子视图:PaintView(UIView的子类)。通过这个视图,我可以跟踪手指的移动并绘制它。

结构如下:

[master.view addSubview: pageView];
[master.view addSubview: paintView];

我知道当用户放大(pageView负责此操作)和委托/方法调用时,我会在缩放操作期间根据缩放更改更改paintView的帧。 缩放(scrollViewDidEndZooming:withView:atScale)后,我调用paintView的自定义重绘方法。

重绘方法和drawRect:

-(void)redrawForScale:(float)scale {
    for (UIBezierPath *path in _pathArray) {
        //TransformMakeScale...
    }
    [self setNeedsDisplay];
} 

-(void)drawRect:(CGRect)rect {
    for (UIBezierPath *path in _pathArray) {
        [path strokeWithBlendMode:kCGBlendModeNormal alpha:1.0];
    } 
}

问题: 当我放大时,我收到内存警告,应用程序崩溃。

在Allocations探查器中,我可以看到应用程序拥有大量内存,但我看不出原因。 如果我在'setNeedDisplay'方法后没有拨打'redrawForScale',那么应用就不会崩溃。

当我在drawRect中记录rect时,我看到如下值:{{0,0.299316},{4688,6630}}。

1 个答案:

答案 0 :(得分:1)

问题是(重新)绘制如此巨大的CGRect(如果这是错误的,请纠正我)。 对我来说,解决方案是避免调用自定义drawRect方法。在一些stackoverflow答案中(我想在Appls文档的某个地方),有人提到自定义drawRect:会降低性能(因为iOS无法在自定义drawRect方法上做一些魔术)。

我的解决方案: 使用CAShapeLayer。对于每个UIBezierPath,我创建一个CAShapeLayer实例,将UIBezierPath添加到图层的path属性,并将该图层作为子图层添加到我的视图中。

CAShapeLayer *shapeLayer = [[CAShapeLayer alloc] initWithLayer:self.layer];
shapeLayer.lineWidth = 10.0;
shapeLayer.strokeColor = [UIColor blackColor].CGColor;
shapeLayer.fillColor = [UIColor clearColor].CGColor;
shapeLayer.path = myBezierPath.CGPath;
[self.layer addSublayer:shapeLayer];

使用此解决方案,我不需要实现drawRect。因此即使有一个很大的最大缩放比例,应用程序也不会崩溃。

更改UIBezierPath(翻译,缩放,更改颜色)后,我需要再次将更改后的bezierPath设置为shapeLayer(再次设置shapeLayer的path属性。)