将现有CGColor分配给CGColor属性适用于iOS模拟器,而不是iOS设备。为什么? [英] Assigning an existing CGColor to a CGColor property works in iOS Simulator, not iOS device. Why?

查看:178
本文介绍了将现有CGColor分配给CGColor属性适用于iOS模拟器,而不是iOS设备。为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道如何解决我即将概述的问题,但是,我有点感到困惑,为什么代码方案在iOS模拟器中有效但在我的iPad上无效。

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.

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

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.

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

The code above works without trouble in the Simulator. However, when I run the application on my iPad, it crashes at the backgroundColor assignment.

我可以通过删除 CGColor 变量并直接从我的开关/中分配背景颜色来解决这个问题。案例陈述,这就是我打算做的事情。

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?

更新

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

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.

这是 #define 语句中的一些语句:

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

我试图简化我的代码,因为编译器应该将refs替换为我的refs到我的定义。不过,为了以防万一,值得一提。

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.

推荐答案

这是我的预感: UIColor可能<在传递 CGColor 之前,已经销毁了创建它(并保持其唯一引用)的/ code>。由于在$ ARC下没有处理 CGColorRef 的引用计数,如果 UIColor ,颜色将是悬空引用在使用 CGColor 之前,它已被销毁。

Here's my hunch: It's possible that the UIColor that created it (and held its only reference) has been destroyed before you pass the CGColor. Since CGColorRef's reference counting is not handled for you under ARC, the color would be a dangling reference if the UIColor that held it were destroyed before you use the CGColor.

ARC有一个优化,其中自动释放对象可能永远不会被添加到自动释放池中,而不是在不再引用objc对象后,已释放。这是三件事的组合:

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:


  1. 您使用的编译器版本和选项。毫不奇怪,编译器添加了引用计数,并且有相应的变化。

  2. ObjC运行时。运行时可以使用线程本地数据。当然,这可能包括你的堆栈。如果您阅读了对象如何绕过自动释放池的详细信息,这应该更清楚。

  3. 您使用的库(包括系统库和框架)。随着编译器和运行时更新,库可能使用ARC,或者它们可能使用不同的运行时调用来执行程序。

了解我怀疑这个程序会纠正这个问题:

Knowing that, I suspect this program would rectify the problem:

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)时,此问题可能会影响您。当您使用的库使用不同版本或编译器设置更新或构建时,也会发生这种情况。例如:如果库在此过程中切换到ARC,它可能会使用不同的运行时调用,或者如果编译器注入的调用被更新,调用可能会以不同方式使用线程本地数据。

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.

有关与运行时相关的ARC规范的详细信息,请参见:
http://clang.llvm.org/docs/AutomaticReferenceCounting.html#runtime

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绘制阴影

这篇关于将现有CGColor分配给CGColor属性适用于iOS模拟器,而不是iOS设备。为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆