Search code examples
iosobjective-cuiviewuicolor

Why does using [UIColor colorWithRed:gred:blue:alpha] lead to EXC_BAD_ACCESS?


I have create a custom UIView subclass which should draw a simple dashed line. To define the color of the line I have added an inspectable property lineColor

// LineView.h
@interface LineView : UIView
@property (nonatomic,assign) IBInspectable UIColor *lineColor;
@end

// LineView.m
- (id)initWithFrame:(CGRect)frame{
    if((self = [super initWithFrame:frame])){
        [self setupView];
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder{
    if((self = [super initWithCoder:aDecoder])){
        [self setupView];
    }
    return self;
}


- (void)setupView {
    self.lineColor = [UIColor colorWithRed:0 green:0 blue:255.0 alpha:1.0];
    //self.lineColor = [UIColor blueColor];  <-- No Problem

    [self refreshLine];
}

- (void)layoutSubviews {
    [super layoutSubviews];
    [self refreshLine];
}

- (void)refreshLine {    
    CGColorRef cgLineColor = self.lineColor.CGColor;  // <--CRASH
    ...
}
  • If a color is assigned in the Interface Builder everything works fine
  • If a default color like [UIColor blueColor] is assigned everything works fine
  • If a custom color like [UIColor colorWithRed:0 green:0 blue:255.0 alpha:1.0] the app crashes with EXC_BAD_ACCESS

[UIDeviceRGBColor respondsToSelector:]: message sent to deallocated instance 0x6000022d08c0

Why is this?


Solution

  • When you use [UIColor blueColor], you don't create the object; you get a reference to it and something else manages its life cycle.

    When you init a new UIColor object, you're responsible for making sure it is still valid when used. "assign" doesn't increase the object's reference count; "strong" does.