2012-01-23 130 views
3

我想向我的UIView添加一个阴影,但是在我的drawRect方法中,我得到了一个EXC_BAD_ACCESS。 (我使用ARC)EXC_BAD_ACCES绘制阴影

-(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;

浮子部件[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); 
} 
+0

在这里发布确切的错误信息。 –

+0

错误消息不会真的有帮助,但为了您的舒适(请参阅编辑)。 – Thys

+0

你的调试器应该至少告诉你哪一行崩溃了。 – DarkDust

回答

2

我看不出有任何理由会崩溃,但尝试使用此代码设置你的颜色,而不是使用CGColorRef。如果它不修复崩溃至少你会知道,线不是问题:

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

现在它在CGContextSetShadowWithColor(context,CGSizeMake(-5,0),10,shadowColor)上崩溃; – Thys

+0

如果您删除该行,会发生什么情况? –

+1

如果您使用CGColorCreate ...方法之一创建阴影Color并在绘制完成后释放它,该怎么办?它不应该是必要的,它更麻烦,但它应该有助于诊断问题是否真的与该线有关。 –

5

UIColor可能不会使它成为一个自动释放池时,ARC的启用。如果没有放入池中并立即释放,那么您引用的(lightColor,shadowColor)CGColor也会在您传递它时被释放,因为它们由UIColor持有/拥有,并且尚未采取任何措施确保这些(非NSObject)引用在该范围之外保持有效。

我无法重现您的具体问题,但我可以用重现:

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

当在SIM V5.0运行。

您是否发布了确切的示例?你在运行什么操作系统版本?它是否发生在所有操作系统版本中?也许你应该看看这个模组。

+0

我希望不是!如果是的话,这将是一个可怕的错误。 –

+0

@尼克是一个ARC转换可能会破坏大量的代码,但这是它的工作原理。 – justin

+0

自启用了阴影的iOS 5以来,Three20表视图也会崩溃。 – xamiro

3

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

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; 
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); 

原因崩溃弧释放临时的UIColor *您刚创建后马上对象。