Search code examples
iphoneuiviewuicolor

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 advance,

Mark


Solution

  • 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...