将现有的CGColor分配给CGColor属性可以在iOS模拟器中使用,而不是iOS设备。 为什么?

我知道如何解决我要概述的问题,但是,为什么代码scheme在iOS模拟器中工作,而不是在我的iPad上,我有点困惑。

我有一个方法,检查各种属性,然后根据属性的状态设置CALayer的背景颜色。 以下代码与我的颜色分配方法类似:

 //This will be the CALayer BGColor... CGColor c = UIColor.blueColor.CGColor; //Blue is the default switch (myState) { case state_one: c = UIColor.greenColor.CGColor; //... more code ... break; case state_two: c = UIColor.redColor.CGColor; //... more code ... break; case state_three: //multiple cases are like the state_three case. //Other code, but I don't need to assign the color. Blue works... } myCALayer.backgroundColor = c; //Oh-noes!!! Here we get the dreaded EXC_BAD_ACCESS on iPad //...more code dealing with the layer. 

上面的代码在模拟器中没有问题。 但是,当我在iPad上运行应用程序时,会在backgroundColor赋值时崩溃。

我可以通过摆脱CGColorvariables并直接在switch / case语句中指定背景颜色来解决这个问题,这就是我正在计划的。

不过,我很好奇。 为什么这个工作在一个环境而不是另一个?

UPDATE

夫妇的事情。 首先,值得一提的是,这是一个使用Xcode 4.2的ARC项目,针对iOS 5设备。 此外,我的颜色分配代码并不完全是它看起来像,因为我有一系列的定义,我用它来设置这些颜色,因为它们在我的应用程序中被引用。

这就是几个#define语句的样子:

 #define BLUE [UIColor colorWithRed:8.0/255.0 green:80.0/255.0 blue:150.0/255.0 alpha:1.0].CGColor #define GREEN (UIColor.blueColor.CGColor) //...and there are about 6 other colors 

我试图简化我的代码,因为编译器应该将ref引用到我的定义中。 不过,值得一提的是以防万一。

这是我的预感:创build它(并且保存唯一参考)的UIColor在通过CGColor之前已经被破坏了。 由于CGColorRef的引用计数在ARC下没有为你处理,所以如果在你使用CGColor之前,保存它的UIColor被破坏了,那么颜色将是一个悬挂参考。

ARC有一个优化,其中“autoreleased”对象可能永远不会被添加到autorelease池,而是在objc对象不再被引用后released 。 这是三件事的结合:

  1. 您使用的编译器版本和选项。 毫不奇怪,编译器添加了引用计数,并且有一些变化。
  2. ObjC运行时。 运行时可以使用线程本地数据。 当然,这可以包括你的堆栈。 如果你阅读一个对象如何绕过自动释放池的细节,这应该更清楚。
  3. 你使用的库(包括系统库和框架)。 当编译器和运行时被更新时,库可能使用ARC,或者它们可能使用不同的运行时调用来执行程序。

知道这个,我怀疑这个scheme会纠正这个问题:

 UIColor * c = UIColor.blueColor; //Blue is the default switch (myState) { case state_one: c = UIColor.greenColor; //... more code ... break; case state_two: c = UIColor.redColor; //... more code ... break; case state_three: //multiple cases are like the state_three case. //Other code, but I don't need to assign the color. Blue works... } myCGLayer.backgroundColor = c.CGColor; //...more code dealing with the layer. 

更详细地说,编译器和objc运行时可以解释和执行你的程序有很多种方法。 这意味着当您更改编译器版本或更新运行时(OS)时,此问题可能会对您产生影响。 当您使用的库更新或使用不同版本或编译器设置构build时,也可能会发生这种情况。 例如:如果库沿途切换到ARC,则可能会使用不同的运行时调用,或者如果编译器注入调用被更新,调用可能会不同地使用线程本地数据。

关于ARC规范与运行时相关的细节可以在这里find: http : //clang.llvm.org/docs/AutomaticReferenceCounting.html#runtime


类似的问题在这里被看到:

EXC_BAD_ACCES绘制阴影

由于ARC,颜色在方法的最后释放得太早。

我使用: CGColorRetain

 CGColorRef whiteColor = CGColorRetain([UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0].CGColor); 

你不会说我们的实例myCGLayer是从myCGLayer派生而来的,但是我会花一点时间说它不是从CGLayer派生的,因为CGLayer没有backgroundColor属性。 所以我猜(再次),传递的参数应该是typesUIColor而不是CGColor。 CGColor从CFType类派生。 UIColor是从NSObject派生的。 它们不应该互换。 如果我的猜测是正确的,我很惊讶它在模拟器中的作品。

如果我的猜测是错误的,不要太苛刻我。