将现有 CGColor 分配给 CGColor 属性适用于 iOS 模拟器,而非 iOS 设备。为什么?
我知道如何解决我即将概述的问题,但是,我有点困惑为什么代码场景在 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
分配时崩溃。
我可以通过删除 CGColor 变量并直接在 switch/case 语句中分配背景颜色来解决此问题,这就是我打算做的。
不过,我很好奇。为什么这在一种环境中有效,而在另一种环境中无效?
更新
一些事情。首先,值得一提的是,这是一个 ARC 项目,使用 Xcode 4.2,针对 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
我尝试简化我的代码,因为编译器应该将我的引用替换为我的定义。不过,为了以防万一,还是值得一提。
I know how to fix the problem that I am about to outline, however, I am a bit baffled as to why the code scenario works in the iOS simulator but not on my iPad.
I have a method that checks various properties, and then sets the background color of a CALayer
depending on the state of a property. The following code is similar to my method of color assignment:
//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.
The code above works without trouble in the Simulator. However, when I run the application on my iPad, it crashes at the backgroundColor
assignment.
I can fix this by getting rid of the CGColor
variable and assigning the background color from directly within my switch/case statement, and that's what I'm planning on doing.
However, I am curious. Why would this work in one environment and not the other?
UPDATE
Couple things. First, it's worth mentioning that this is an ARC project, using Xcode 4.2, targeting iOS 5 devices. Also, my color assignement code isn't entirely what it looks like because I have a series of defines that I use to set these colors because they are referenced all throughout my application.
This is what a few of the #define
statements looks like:
#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
I tried to simplify my code because the compiler should replace the refs to my refs to my defines. Still, it's worth mentioning just in case.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
由于 ARC,颜色在方法结束时过早释放。
我使用:CGColorRetain
Because of ARC the color is released too early in the end of the method.
i use: CGColorRetain
我的预感是:在传递
CGColor
之前,创建它(并保存其唯一引用)的UIColor
可能已被销毁。由于在 ARC 下,CGColorRef
的引用计数不会为您处理,因此,如果在使用之前保存颜色的
。UIColor
被销毁,则该颜色将是悬空引用。 CG颜色ARC 有一项优化,其中“自动释放”对象可能永远不会添加到自动释放池中,而是在 objc 对象不再被引用后
释放
。这是三件事的组合:知道了这一点,我怀疑这个程序会纠正这个问题:
更详细地说,编译器和 objc 运行时可以通过多种方式解释和执行您的程序。这意味着当您更改编译器版本或更新运行时 (OS) 时,此问题可能会影响您。当您使用的库更新或使用不同版本或编译器设置构建时,也可能会发生这种情况。例如:如果库一路切换到 ARC,它可能会使用不同的运行时调用,或者如果更新了编译器注入的调用,这些调用可能会以不同的方式利用线程本地数据。
有关 ARC 规范与运行时相关的详细信息可以在此处找到:
http://clang.llvm.org/docs/AutomaticReferenceCounting.html#runtime
这里也出现过类似的问题:
EXC_BAD_ACCES绘制阴影
Here's my hunch: It's possible that the
UIColor
that created it (and held its only reference) has been destroyed before you pass theCGColor
. SinceCGColorRef
's reference counting is not handled for you under ARC, the color would be a dangling reference if theUIColor
that held it were destroyed before you use theCGColor
.ARC has an optimization where "autoreleased" objects may never be added to an autorelease pools, and instead,
released
after the objc object is no longer referenced. This is a combination of three things:Knowing that, I suspect this program would rectify the problem:
In more detail, there are number of ways the compiler and the objc runtime can interpret and execute your program. This means that this problem could affect you when you change compiler versions, or when the runtime (OS) is updated. It can also happen as the libraries you use are updated or built with different versions or compiler settings. For example: If the library switches to ARC along the way, it may use a different runtime calls, or the calls may utilize thread local data differently if the compiler injected calls are updated.
Details about the ARC spec as it relates to the runtime can be found here:
http://clang.llvm.org/docs/AutomaticReferenceCounting.html#runtime
A similar problem was seen here:
EXC_BAD_ACCES drawing shadow
你没有说你的实例
myCGLayer
是从什么派生的,但我会说它不是从CGLayer派生的,因为CGLayer没有backgroundColor
财产。所以我(再次)猜测,传递的参数应该是 UIColor 类型而不是 CGColor 类型。 CGColor 派生自 CFType 类。 UIColor 派生自 NSObject。它们不应该互换。如果我的猜测是正确的,我很惊讶它能在模拟器中工作。如果我的猜测是错误的,请不要太用力地打我。
You don't say what your instance
myCGLayer
us derived from, but I'll take a shot and say it's not derived from CGLayer, because CGLayer doesn't have abackgroundColor
property. So I'm guessing (again), the parameter passed should be of type UIColor and not CGColor. CGColor is derived from class CFType. UIColor is derived from NSObject. They shouldn't be interchangeable. If my guesses are right, I'm surprised it works in the simulator.Don't slap me too hard if my guesses are wrong.