Crashing while passing UIColor as argument
I have a little UIView object, CircleColorView.m, that simply creates a view with a colored circle in it. I then use that view as the background to a bunch of buttons (all different colors).
My problem happens when the drawRect: method gets called. I crash, but only sometimes, when I reference the object color which is a UIColor.
I am very confused. Here is my UIView:
ColorCircleView.h
#import <UIKit/UIKit.h>
#import "Constants.h"
@interface CircleColorView : UIView {
UIColor *color;
}
@property (nonatomic, retain) UIColor *color;
- (id)initWithFrame:(CGRect)frame andColor:(UIColor *)circleColor;
@end
And here is ColorCircleView.m
#import "CircleColorView.h"
@implementation CircleColorView
@synthesize color;
- (id)initWithFrame:(CGRect)frame andColor:(UIColor *)circleColor {
if ((self = [super initWithFrame:frame])) {
color = [UIColor colorWithCGColor:[circleColor CGColor]];
// have also tried
// color = circleColor;
}
return self;
}
- (void) drawRect: (CGRect) aRect
{
CGFloat iconSize = self.frame.size.width;
// Create a new path
CGContextRef context = UIGraphicsGetCurrentContext();
CGMutablePathRef path = CGPathCreateMutable();
// Set up fill for circle
const CGFloat* fill = CGColorGetComponents(color.CGColor);
CGContextSetFillColor(context, fill);
// Add circle to path
CGRect limits = CGRectMake(8.0f, 8.0f, iconSize - 16.0f, iconSize - 16.0f);
CGPathAddEllipseInRect(path, NULL, limits);
CGContextAddPath(context, path);
CGContextFillEllipseInRect(context, limits);
CGContextFillPath(context);
CFRelease(path);
}
- (void)dealloc {
[color release];
[super dealloc];
}
@end
Here is the code that I use to create and add the CircleColorView to a button image. It is inside a loop that is going through an array of strings with color values separated by a ;
NSArray *values = [[NSArray alloc] initWithArray:[[[colorListArray objectAtIndex:i] objectAtIndex:1] componentsSeparatedByString:@";"]];
float red = [[values objectAtIndex:0] floatValue];
float green = [[values objectAtIndex:1] floatValue];
float blue = [[values objectAtIndex:2] floatValue];
UIColor *color = [[UIColor alloc]
initWithRed: (float) (red/255.0f)
green: (float) (green/255.0f)
blue: (float) (blue/255.0f)
alpha: 1.0];
UIButton *newColorButton = [UIButton buttonWithType:0];
//Create Colored Circle
CircleColorView *circle = [[CircleColorView alloc] initWithFrame:CGRectMake(0, 0, 75, 75) andColor:color ];
circle.backgroundColor = [UIColor clearColor];
//Set Button Attributes
[newColorButton setTitle:[[colorListArray objectAtIndex:i] objectAtIndex:1] forState:UIControlStateDisabled];
[newColorButton setFrame:CGRectMake(600+(i*82), 12, 75, 75)]; //set location of each button in scrollview
[newColorButton addTarget:self action:@selector(changeColor:) forControlEvents:UIControlEventTouchDown];
[newColorButton setTag:tagNum];
[barContentView addSubview:newColorButton];
[circle release];
[color release];
[values release];
I've logged it to see what happens. Looks like it runs CircleColorView's initWithFrame:andColor: just fine. Then when the drawRect: is called, it will crash the first time the property 'color' is referenced. Even if it is just asking it for a discription like [color description].
Any ideas. Am I creating this UIColor *color wrong? Or retaining it wrong? Here is another strange thing. This code runs just fine for a while. Then when I quit and restart the app it will crash. To get it to work again I have deleted the build file and the app folder in the iPhone simulator. That will allow it to work again. The only other thing that will consistantly get it to work is by just changing the UIColor *color @property to assign or vice versa. That will allow me to rebuild the app and run it with no problems once or twice again. Then it crashes. Oh, and it does the same thing on the device. Any ideas???
Thanks in adva开发者_如何学Pythonnce,
Mark
This line declares the color property, which will retain the color when assigned.
@property (nonatomic, retain) UIColor *color;
This line bypasses the property setter and assigns an autoreleased object directly to the member.
color = [UIColor colorWith...
You can fix it with either:
self.color = [UIColor colorWith...
or
[color retain];
or
color = [[UIColor alloc] initWith...
Because you are assigning directly to "color", and not using the "." accessor syntax, the setter method is not getting called, so the value you're assigning isn't retained.
You need to either explicitly retain color
, or use the . syntax:
self.color = [UIColor colorWithCGColor:[circleColor CGColor]];
color = [UIColor colorWithCGColor:[circleColor CGColor]];
[color retain];
By not having the [color retain]
code it is autoreleased and that will randomly happen.
You wouldn't need the [color retain]
if your did something like color = [[UIColor alloc] initWithCGColor:[circleColor CGColor]];
or something similar that had init in the creation.
精彩评论