我正在做的是绘制一个简单的矩形并为绘制区域设置颜色
// 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;
然后我可以在设备上运行该应用程序。我根本得不到它
答案 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
。