drawRect在更快的设备上的奇怪行为

时间:2012-03-20 15:38:15

标签: objective-c ios exc-bad-access drawrect

好的,我有一个包含属性cgpath的虚拟对象数组。这在我的UIView中称为darkPathArray属性。

当我一个接一个地画它们时,我发现了一件有趣的事情。在iOS 5 sim / device上运行时,我在CGContextAddPath(context,ppath.path);ppath.path抛出那个)上获得了EXC_BAD_ACCESS。但是当我在NSLog前面发出CGContextAddPath来电时,它可以正常工作。这就是,因为它显着减慢了。

所以问题在于-drawRect召唤的频率。没关系,我可以假装它,直到我做到了,但这不是专业人士的工作方式。

因此,我在问为什么会发生这种情况?

-(void)drawRect:(CGRect)r
{
    // Get the graphics context and clear it
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextClearRect(context, self.bounds);

    [[UIColor whiteColor] set];
    UIRectFill ([self bounds]);

    // Draw every single section as a path
    for (ShopSection *section in self.shopSectionsArray) {
        // Draw the walls
        [section.darkColor setFill];

        for (MMPath *ppath in section.darkPathArray) {
            CGContextAddPath(context,ppath.path);
            CGContextDrawPath(context, kCGPathFill);
        }
    }
}

编辑: 启用ARC

MMPaths没有改变

EXC_BAD_ACCESS正在响应坏节对象/不知道为什么(它们被安全地存储在数组中)

Superview:UIScrollView 图层:CATiledLayer

在快速重新绘制内容时 - 在快速设备/模拟器上或大幅滚动和缩放时,会出现访问不良的问题。

EDIT2: 我想我明白了!问题是CATiledLayer使用背景线程,所以它以某种方式捕获它的尾巴。有谁知道如何解决这个问题?最好的方法是什么?我做错了什么?

2 个答案:

答案 0 :(得分:1)

此循环不正确:

for (MMPath *ppath in section.darkPathArray) {
    CGContextAddPath(context,ppath.path);
    CGContextDrawPath(context, kCGPathFill);
}

CGContextAddPath()增加了“当前路径”。 CGContextDrawPath绘制“当前路径”。所以你继续扩展路径,然后重新绘制所有内容。你的意思是:

for (ShopSection *section in self.shopSectionsArray) {

    // Draw the walls
    [section.darkColor setFill];

    for (MMPath *ppath in section.darkPathArray) {
        CGContextAddPath(context,ppath.path);
    }
}
CGContextDrawPath(context, kCGPathFill);

答案 1 :(得分:0)

我终于改变主意并使用了CAShapeLayer而不是我的MMPath(带有CGPath属性的NSObject)。然后使用CGRectIntersectsRect,我设法摆脱了那个多线程错误。 它也意味着最优化,因为每个矩形中只绘制适当的形状。

这就是如何绘制CATiledLayer中的多个形状:

-(void)drawRect:(CGRect)rect
{
// Get the graphics context and clear it
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClearRect(context, self.bounds);

[[UIColor whiteColor] set];
UIRectFill ([self bounds]);

// Draw every single section as a path
for (ShopSection *section in self.shopSectionsArray) {

    CAShapeLayer *s = section.wallsShapeLayer;
    // Draw the walls
    if ( CGRectIntersectsRect(rect, s.frame ) )
    {
        // Rasterising before rendering enhances the performance a bit
        s.shouldRasterize = YES;
        [s renderInContext:context];
    }
}
}