在设备核心图形中安装应用程序时获取EXC_BAD_ACCESS

时间:2012-10-20 05:34:18

标签: ios core-graphics drawrect

我正在做的是绘制一个简单的矩形并为绘制区域设置颜色

   // Just added
    @interface Gradient () {
       CGColorRef  lightBlueColor;
   }
    @implementation Gradient

    -(id)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            self.backgroundColor   =   [UIColor lightGrayColor];
            NSLog(@"frame is %@",NSStringFromCGRect(self.frame));
            NSLog(@"bound is %@",NSStringFromCGRect(self.bounds));
            lightBlueColor         =   [UIColor colorWithRed:105.0f/255.0f green:179.0f/255.0f blue:216.0f/255.0f alpha:1.0].CGColor;

        }
        return self;
    }

    -(void) layoutSubviews {
        paperRect =   CGRectMake(10, 10, self.bounds.size.width/2, self.bounds.size.height/2);
    }

    -(void)drawRect:(CGRect)rect {

        //Draw a retangle
        CGContextRef        context     =   UIGraphicsGetCurrentContext();

        CGContextSetFillColorWithColor(context, lightBlueColor);
        CGContextFillRect(context, paperRect);  


    }

以下是模拟器上显示的内容

enter image description here

但是,当我尝试在设备上安装时,我正在获得EXC_BAD_ACCESS enter image description here

问题:

为什么它无法在设备上运行。我在某处犯了错误

编辑:我刚刚尝试修改lightBlueColor

  

lightBlueColor = [UIColor blueColor] .CGColor;

然后我可以在设备上运行该应用程序。我根本得不到它

2 个答案:

答案 0 :(得分:3)

编辑,因此您遇到了内存管理问题。从理论上讲,在这两种情况下,程序都可能崩溃。为什么?因为根据文档,-[UIColor lightBlueColor]及其附带的类方法返回一个自动释放的对象。实际上,出于优化原因,事实并非如此:实际上,为了节省内存,它们返回相同的alloc-initied单例。这种优化是可能的,因为它们总是返回相同的颜色。由于共享实例(单例颜色)是在没有自动释放的情况下创建的,因此当您不期望它时,它不会突然释放,这就是程序工作的原因。如果Apple的程序员不够聪明,无法进行优化,那么这两个程序都会崩溃。

但在第二种情况下,colorWithRed:green:blue:alpha:方法不可能进行此优化,因为它不能保证它始终返回相同的颜色。 (想象一下,如果你先调用它来获得红色,然后将其缓存,然后你想获得蓝色,但它会返回缓存的红色,会发生什么。)所以它实际上创建了一个新的实例颜色和自动释放它。但是由于您没有保留它,很快就会因为自动释放而被释放,因此其CGColor属性也会失效。因此,有三种可能的解决方案:

一。我更喜欢这个。将lightBlueColor实例变量设为UIColor对象,并使用

创建它
lightBlueColor = [[UIColor alloc] initWithRed:r green:g blue:b alpha:a];

然后只使用其CGColor属性进行绘制。

两个。与第一个类似,但您可以将颜色对象创建为

lightBlueColor = [[UIColor colorWithRed:r green:g blue:b alpha:a] retain];

同样,但我认为这是一个错误的概念。

三:您可以让UIColor对象在自动释放池的深井中消失,但保持CGColor安全:

lightBlueColor = CGColorRetain([UIColor colorWithRed:r green:g blue:b alpha:a].CGColor);

在每种情况下,您都应该注意dealloc方法中的内存管理。

经验教训:实例变量不适合存储自动释放的对象。你想在适当的时候分配init-release。

答案 1 :(得分:1)

您的问题似乎是内存管理问题。您不能在CGColorRetain方法中的 lightBlueColor 上致电init。它适用于UIColor blueColor,因为该颜色是操作系统保持的常量。你的颜色不是那么超出范围并被取消分配。

添加后,请不要忘记根据需要在CFColorRelease或任何其他适当的地方致电dealloc