关于CGColor /定义

问题描述 投票:2回答:2

在类中我有一个CGColorRef类型的变量myColor声明如下:

@implementation MyClass
{
    .......
    CGColorRef myColor;
    .......

以下是两行Objective C代码:

第一行:

myColor=[UIColor orangeColor].CGColor;

第二行:

myColor=[UIColor colorWithRed:1.000 green:0.500 blue:0.000 alpha:1.000].CGColor;

我首先预计它们是等价的,但事实并非如此。

我知道它们不相同,因为当我使用第一个时,我的程序可以工作。当我使用第二个时,它会在后来的路上崩溃。在这里显示更多代码与问题完全无关。

有人可以解释这个区别吗?这将有希望允许我修改我的代码并能够使用第二行。

仅供参考,它崩溃(使用:线程1:EXC_BAD_ACCESS(代码= 1,地址= 0x881b370e0)):

- (void)drawRect:(CGRect)rect
{
    .......
    CGContextSetStrokeColorWithColor(context,myColor); // Crash here !!!
    CGContextStrokeEllipseInRect(context, rectangle);
    .......
}
ios objective-c cgcolor
2个回答
1
投票

崩溃是因为你可能没有强大的myColor对象的ref(属性)。你可能有assign财产

[UIColor orangeColor]工作的原因,但不是[UIColor colorWithRed...

使用[UIColor orangeColor]时,不创建对象;你得到一个参考,其他东西管理它的生命周期。

当您初始化一个新的UIColor对象时,您有责任确保它在使用时仍然有效。 “assign”不会增加对象的引用计数; “强”的确如此。

希望它有所帮助

编辑

声明这样的一个属性

@property (nonatomic,strong) UIColor * myUIColor;

现在什么时候可以

这样做

myUIColor =[UIColor colorWithRed:1.000 green:0.500 blue:0.000 alpha:1.000]

什么时候需要CGColor

myUIColor. CGColor


3
投票

您正在分配Core Foundation类型CGColorRef的实例变量。该类型不是ObjC对象类型,因此不受ARC(自动内存管理)的约束,这意味着您需要手动管理其内存。

你的两个例子实际上都是不正确的,但是你在分配[UIColor orangeColor].CGColor时最初没有看到崩溃的原因是因为一个幸运的巧合:橙色对象可能是一个长寿命的单例对象,因此它的内部CGColor参考是也是长寿的,所以你对ivar的工作和以后的访问恰好工作 - 但这只是一个红色(橙色?)鲱鱼。

你确实看到了另一种情况下的崩溃,因为你在传递过程中创建的UIColor对象最终被立即释放,因为它没有被再次使用。因此,当您尝试稍后使用时,您从中提取并分配给您的ivar的CGColorRef值也会立即无效且具有放射性。

要将CGColorRef安全地存储在您的对象中,您需要拥有它,在您的情况下意味着明确保留您从CGColorRef获得的UIColor

myColor = CGColorRetain([UIColor colorWithRed:1.000 green:0.500 blue:0.000 alpha:1.000].CGColor);

或者更好的方法是完全绕过UIColor,只需使用直接为您提供颜色引用的函数,并创建所有权语义:

myColor = CGColorCreateGenericRGB(1.0, 0.5, 0.0, 1.0);

在任何一种情况下,你现在都“拥有”这个引用,这意味着以后使用它是安全的,也意味着你有责任在你完成后清理它,例如:

- (void)dealloc 
{
    CGColorRelease(myColor);
}

另见this Apple Tech Q&A doc,几乎就是这个例子。


Core Foundation对象所需的内存管理形式(CGColorRef就是其中之一)与旧的ARC ObjC手动系统非常相似,您可以在该系统中增加保留计数(“拥有”)引用,然后在不再需要它有效时递减(释放)。 Apple has good docs如何最好地考虑这一点。在这种情况下,为实例变量分配引用意味着您希望将其保持有效一段时间。通常,您保留在赋值点(显式或通过Create function获取引用),然后在释放对象时释放它。

热门问题
推荐问题
最新问题