EXC_BAD_ACCESS绘图阴影

时间:2012-01-23 16:21:59

标签: ios uiview core-graphics automatic-ref-counting cgcontext

我正在尝试为我的UIView添加一个阴影,但在我的drawRect方法中,我获得了一个EXC_BAD_ACCESS。 (我正在使用ARC)

-(void) drawRect:(CGRect)rect {

    CGColorRef lightColor =  [UIColor colorWithRed:105.0f/255.0f green:179.0f/255.0f blue:216.0f/255.0f alpha:0.8].CGColor;

    CGColorRef shadowColor = [UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:0.4].CGColor;   

    CGContextRef context = UIGraphicsGetCurrentContext();
    // Draw shadow
    CGContextSaveGState(context);
    CGContextSetShadowWithColor(context, CGSizeMake(-5, 0), 10, shadowColor);
    CGContextSetFillColorWithColor(context, lightColor);
    CGContextFillRect(context, _coloredBoxRect);
    CGContextRestoreGState(context);
}

错误消息: 线程1:编程接收信号:“EXC_BAD_ACCESS”。

行: CGContextSetFillColorWithColor(context, lightColor);

当我将此行更改为:

[[UIColor colorWithRed:105.0f/255.0f green:179.0f/255.0f blue:216.0f/255.0f alpha:0.8] setFill];

我得到了相同的错误,但是在这一行:

CGContextSetShadowWithColor(context, CGSizeMake(-5, 0), 10, shadowColor);

更新 我最后通过改变来解决这个问题:

CGColorRef shadowColor = [UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:0.4] .CGColor;

float components [4] = {0,0,0,1.0 / 3.0}; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGColorRef shadowColor = CGColorCreate(colorSpace,components);

最终(工作)代码:

-(void) drawRect:(CGRect)rect 
{
    float components[4] = {0, 0, 0, 1.0/3.0};
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGColorRef shadowColor = CGColorCreate( colorSpace, components);

    CGContextRef context = UIGraphicsGetCurrentContext();

    // Draw shadow
    CGContextSaveGState(context);
    CGContextSetShadowWithColor(context, CGSizeMake(-5, 0), 10, shadowColor);
    CGContextSetFillColorWithColor(context, lightColor);

    [[UIColor colorWithRed:105.0f/255.0f green:179.0f/255.0f blue:216.0f/255.0f alpha:0.8] setFill];

    CGContextRestoreGState(context);
}

4 个答案:

答案 0 :(得分:5)

启用ARC时,UIColor可能无法进入自动释放池。如果它没有被放入池并立即释放,那么你引用的CGColor(lightColor,shadowColor)也会在你传递它时被解除分配,因为它们由UIColor持有/拥有,并没有采取措施确保这些(非NSObject)引用在该范围之外仍然有效。

我无法重现您的确切问题,但我可以使用以下方式重现它:

CGColorRef shadowColor =
  [[UIColor alloc] initWithRed:0.2 green:0.2 blue:0.2 alpha:0.4].CGColor;

在sim v5.0上运行时。

你发布了确切的例子吗?您运行的操作系统版本是什么?是否会在所有操作系统版本中发生?也许你应该看看asm。

答案 1 :(得分:3)

或者,您可以告诉编译器将您的UIColor对象添加到自动释放池中,而不是立即释放它们。

UIColor * __autoreleasing lightUIColor = [UIColor colorWithRed:105.0f/255.0f green:179.0f/255.0f blue:216.0f/255.0f alpha:0.8];
CGColorRef lightColor =  lightUIColor.CGColor;

UIColor * __autoreleasing shadowUIColor = [UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:0.4];
CGColorRef shadowColor = shadowUIColor.CGColor;   

答案 2 :(得分:2)

我看不出有什么原因会崩溃,但尝试使用此代码设置颜色而不是使用CGColorRef。如果它不能解决崩溃,至少你会知道这条线不是问题所在:

[[UIColor colorWithRed:105.0f/255.0f green:179.0f/255.0f blue:216.0f/255.0f alpha:0.8] setFill];

答案 3 :(得分:0)

以下代码将满足ARC:

UIColor *lightColor =  [UIColor colorWithRed:105.0f/255.0f green:179.0f/255.0f blue:216.0f/255.0f alpha:0.8];
...
CGContextSetFillColorWithColor(context, lightColor.CGColor);

ARC在您创建临时UIColor *对象后立即解除分配的原因。