1

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

   // 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);  


    }

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

在此处输入图像描述

但是,当我尝试在设备上安装时,我收到 EXC_BAD_ACCESS 在此处输入图像描述

问题 :

为什么它在设备上不起作用。我在某处犯错了吗

编辑:我刚刚尝试修改 lightBlueColor

lightBlueColor = [UIColor blueColor].CGColor;

然后我可以在设备上运行该应用程序。我完全不明白

4

2 回答 2

3

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

但在第二种情况下,该colorWithRed:green:blue:alpha:方法不可能有这种优化,因为不能保证它总是返回相同的颜色。(想象一下,如果你先调用它来获取红色,然后它会缓存它,然后你想获取蓝色,但它会返回缓存的红色。)所以它实际上创建了一个新的实例 a颜色并自动释放它。但是由于您不保留它,它很快就会因为自动释放而被释放,因此它的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方法中的内存管理。

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

于 2012-10-20T06:04:35.747 回答
1

您的问题似乎是内存管理之一。你没有CGColorRetain在你的方法中调用lightBlueColor 。initUIColor blueColor很可能适用,因为该颜色是操作系统保留的一些常量。您的颜色不是这样,它超出了范围并被释放。

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

于 2012-10-20T06:22:49.593 回答