OGeek|极客世界-中国程序员成长平台

标题: ios - 关于 CGColor/定义 [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-13 16:11
标题: ios - 关于 CGColor/定义

在一个类中,我有一个 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 (code=1, address=0x881b370e0)):

- (void)drawRectCGRect)rect
{
    .......
    CGContextSetStrokeColorWithColor(context,myColor); // Crash here !!!
    CGContextStrokeEllipseInRect(context, rectangle);
    .......
}



Best Answer-推荐答案


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

您的两个示例实际上都不正确,但是当您分配 [UIColor orangeColor].CGColor 时最初看不到崩溃的原因是幸运的巧合:橙色对象是可能是一个长期存在的单例对象,因此它的内部 CGColor 引用也是长期存在的,因此您对 ivar 的分配有效,并且稍后的访问恰好有效——但这只是一个红色(橙色? ) 鲱鱼。

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

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

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 之前的手动系统非常相似,在该系统中,您在该点增加保留计数您希望保留(“拥有”)引用的位置,然后在您不再需要它有效时减少(释放)。苹果has good docs如何最好地考虑这一点。在这种情况下,将引用分配给您的实例变量意味着您希望它在一段时间内保持有效。通常,您在分配点保留(明确地或通过 Create function 获取引用),然后在对象被释放时释放它。

关于ios - 关于 CGColor/定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55719382/






欢迎光临 OGeek|极客世界-中国程序员成长平台 (http://ogeek.cn/) Powered by Discuz! X3.4