为什么使用#define UIColor作为CGColorRef会导致崩溃?

问题描述:

我有这样定义的的UIColor:为什么使用#define UIColor作为CGColorRef会导致崩溃?

#define kCircleInnerShadowColor [UIColor colorWithWhite:.78 alpha:1.0] 

然后我用这样的:

CGColorRef shadowColorRef = kCircleInnerShadowColor.CGColor; 
CGContextSetShadowWithColor(cxt, size, 0, shadowColorRef); 

然而,这导致BAD_ACCESS崩溃。如果我反而做

CGContextSetShadowWithColor(cxt, size, 0, kCircleInnerShadowColor.CGColor); 

我不会崩溃,它工作正常。这是什么原因?

它崩溃的原因是因为范围问题。 你在做什么是:

  1. 创建一个新的UIColor对象
  2. 检索其CGColor指针
  3. 把那个指针到一个新的变量
  4. 松开的UIColor对象(下一行...)
  5. 使用CGColor指针,它指向错误的数据已经

当您在“一行版”做到这一点,你做的是:

  1. 创建一个新的UIColor对象
  2. 检索其CGColor指针
  3. 使用CGColor指针的函数
  4. 松开的UIColor对象(下一行...)

因此,因为您在使用它的同一行中创建对象,编译器会自动保留对象,直到函数调用返回并继续到下一行。只有这样它才能释放对象。

但是,当您将CGColor设置为变量时,会发生什么情况是编译器认为该对象不会在任何地方使用,并发送一个版本。但CGColor不是NSObject,编译器不会发送“保留”到CGColor。

如果您需要变量中的CGColor,您可能需要使用CGColorRetain

CGColorRef shadowColorRef = CGColorRetain(kCircleInnerShadowColor.CGColor); 

然后当你完成它,CGColorRelease

+2

这是有效的,“内部指针”的问题(正是因为丹尼尔介绍)。如果使用这种颜色,一个可能更好的解决方案*很多*是有一个全局变量,而不是#define,以避免大量的内存流量。 – bbum

+0

如何创建全局UIColor变量? – Snowman

+0

哪一行是释放CGColorRef? – Snowman