将UIColor传递给方法和应用程序崩溃

时间:2010-06-27 06:14:38

标签: objective-c iphone

参见代码,界面

@interface ColorPreview : UIView {
    UIColor *backgroundColor;
}
@property (retain) UIColor *backgroundColor;

-(void) reDrawPreviewWith:(UIColor *)bgColor;

@end

实施

@implementation ColorPreview

@synthesize backgroundColor;
- (id)initWithFrame:(CGRect)frame {

    if ((self = [super initWithFrame:frame])) {
        // Initialization code
        backgroundColor = [[UIColor alloc] init];
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    ............
    //app crashes on this line
    CGContextSetFillColorWithColor(context, [backgroundColor CGColor]);

    NSLog(@"rect");
}

-(void) reDrawPreviewWith:(UIColor *)bgColor 
{
    backgroundColor = bgColor;
    [self setNeedsDisplay];
}

- (void)dealloc {
    [backgroundColor release];
    [super dealloc];
}

@end

像这样调用我的方法

[preview reDrawPreviewWith:[UIColor colorWithRed:red green:green blue:blue alpha:1.0]];

1 个答案:

答案 0 :(得分:3)

加里几乎是对的:
导致崩溃的原因是你不是真的设置你在reDrawPreviewWithColor:中获得的颜色作为参数 - 事实上,你的reDraw...几乎从不工作正确:它要么保留对它不拥有的对象的引用,即。 在自动释放的对象上崩溃(您所看到的)或泄漏

所以这是一个修复:

-(void)reDrawPreviewWithColor:(UIColor *)newColor
{
  [self setBackgroundColor: newColor];  // or use the dot-syntax if you please ;-)
  [self setNeedsDisplay];
}

甚至更好地废弃reDraw...,而是为backgroundColor编写自己的setter,因为无论如何都要重新绘制颜色:

-(void)setBackgroundColor:(UIColor *)newColor
{
    if (backgroundColor == newColor) 
      return; // if they are *identical*, there's nothing to do

    [newColor retain];
    @synchronize(self)
    {
        [backgroundColor release];
        backgroundColor = newColor;
        [self setNeedsDisplay];
    }
}

哦,当我们在它的时候:
backgroundColor是原子属性有充分的理由吗?您可能需要考虑将其声明为

@property (nonatomic, retain) UIColor *backgroundColor;

这样你就可以从我提出的setter中删除@synchronize指令。


重要的东西作为旁白:
Gary建议在self.backgroundColor = [[UIColor alloc] init]中写initWithFrame:

不要!

你拥有alloc你拥有的东西,所以如果你想要拥有它两次 Ur Doin'它错了!™ - 但你已经拥有了这个权利,所以我认为你意识到这一点。