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

查看:20
本文介绍了将现有的 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 变量并直接从我的 switch/case 语句中分配背景颜色来解决这个问题,这就是我计划做的.

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

我试图简化我的代码,因为编译器应该将引用替换为我的定义的引用.不过,还是值得一提,以防万一.

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.

推荐答案

这是我的预感:在您通过CGColor.由于 CGColorRef 的引用计数不是在 ARC 下为你处理的,如果在你使用 之前销毁它的 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 对象之后 released.这是三件事的结合:

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天全站免登陆