【问题标题】:getting EXC_BAD_ACCESS when installing the app in device, core graphic在设备中安装应用程序时获取 EXC_BAD_ACCESS,核心图形
【发布时间】:2012-10-20 05:34:18
【问题描述】:

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

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

然后我可以在设备上运行应用程序。完全没看懂

【问题讨论】:

    标签: ios core-graphics drawrect


    【解决方案1】:

    编辑:所以您遇到了内存管理问题。理论上,在这两种情况下,程序都可能崩溃。为什么?因为根据文档,-[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方法中的内存管理。

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

    【讨论】:

    • 对不起,我不明白。原来的 lightBlueColor 被定义为lightBlueColor = [UIColor colorWithRed:105.0f/255.0f green:179.0f/255.0f blue:216.0f/255.0f alpha:1.0].CGColor;,虽然它是 CGColorRef 类型
    • @ttran 所以它在设备上运行或不运行仅取决于您调用colorWithRed:green:blue:alpha: 还是blueColor
    • iOS 版本有时会出现问题,因为可能是在新 iOS 中贬值了,请检查一下
    • @PREMKUMAR 从 iOS 4、5 和 6 开始,这些方法都没有被弃用。
    • @(H2CO3 和 maddy):再次感谢你们。两者的绿色检查:))
    【解决方案2】:

    您的问题似乎是内存管理问题之一。您不会在 init 方法中的 lightBlueColor 上调用 CGColorRetain。它很可能适用于UIColor blueColor,因为该颜色在操作系统中保持不变。你的颜色不是,所以它超出范围并被释放。

    添加后,请不要忘记在dealloc 或任何其他需要的适当位置致电CFColorRelease

    【讨论】:

    • 感谢您的回答。如果我能做两次绿色检查,我也会为你做。
    猜你喜欢
    • 1970-01-01
    • 2017-05-29
    • 2012-07-16
    • 2016-09-14
    • 2021-08-12
    • 1970-01-01
    • 2011-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多