问题
I am trying to add a shadow to my UIView, but in my drawRect method I get an EXC_BAD_ACCESS. (I am using 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);
}
Error Message: Thread 1: Program received signal: "EXC_BAD_ACCESS".
Line: CGContextSetFillColorWithColor(context, lightColor);
When I change this line to:
[[UIColor colorWithRed:105.0f/255.0f green:179.0f/255.0f blue:216.0f/255.0f alpha:0.8] setFill];
I get the same error but on this line:
CGContextSetShadowWithColor(context, CGSizeMake(-5, 0), 10, shadowColor);
Update I finally resolved the issue by changing:
CGColorRef shadowColor = [UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:0.4].CGColor;
to
float components[4] = {0, 0, 0, 1.0/3.0}; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGColorRef shadowColor = CGColorCreate( colorSpace, components);
The eventual (working) code:
-(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);
}
回答1:
I can't see any reason why that would crash, but try setting your color using this code instead of using a CGColorRef. If it doesn't fix the crash at least you'll know that line wasn't the problem:
[[UIColor colorWithRed:105.0f/255.0f green:179.0f/255.0f blue:216.0f/255.0f alpha:0.8] setFill];
回答2:
The UIColor
may not make it into an autorelease pool when ARC's enabled. If it is not put in a pool and immediately released, the CGColor
s you reference (lightColor, shadowColor) would also have been deallocated by the time you pass it because they are held/owned by the UIColor
, and no measure has been taken to ensure that these (non-NSObject
) references remain valid beyond that scope.
I can't reproduce your exact issue, but I can reproduce it using:
CGColorRef shadowColor =
[[UIColor alloc] initWithRed:0.2 green:0.2 blue:0.2 alpha:0.4].CGColor;
when run on the sim v5.0.
Have you posted the exact example? What OS version are you running on? Does it happen in all OS versions? Perhaps you should have a peek at the asm.
回答3:
Alternately you can tell the compiler to add your UIColor
objects to the autorelease pool and not immediately release them.
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;
回答4:
The below code will satisfy 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);
The reason for a crash that ARC deallocated interim UIColor* object just right after you created it.
来源:https://stackoverflow.com/questions/8974910/exc-bad-acces-drawing-shadow