CG Gradient在模拟器上运行,但在iPhone上运行 [英] CG Gradient runs on simulator, but not on iPhone

查看:135
本文介绍了CG Gradient在模拟器上运行,但在iPhone上运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个编译没有问题的代码。它在iPhone模拟器上运行良好,但在我的设备上,我得到一个EXC_BAD_ACCESS。

I have a code that compile without problems. It runs well on the iPhone simulator, but on my device, I get an EXC_BAD_ACCESS.

这在辅助函数中发生以绘制渐变。我按照本教程进行操作。我的代码如下:

This happens in a helper function to draw gradient. I followed this tutorial to do it. The code I have is as follows:

- (void) drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGColorRef whiteColor = [UIColor whiteColor].CGColor;
    CGColorRef lightGrayColor = [UIColor colorWithRed:230.0/255.0
                                                green:230.0/255.0 
                                                 blue:230.0/255.0 
                                                alpha:1.0].CGColor;
    CGColorRef separatorColor = [UIColor colorWithRed:208.0/255.0
                                                green:208.0/255.0 
                                                 blue:208.0/255.0
                                                alpha:1.0].CGColor;
    CGRect paperRect = self.bounds;
    CGRect nameRect = self.nameLabel.frame;
    CGPoint sepStartPoint = CGPointMake(nameRect.origin.x, 
                                        nameRect.origin.x + nameRect.size.height + 2);
    CGPoint sepEndPoint = CGPointMake(nameRect.origin.x + nameRect.size.width, 
                                      nameRect.origin.x + nameRect.size.height + 2);

    drawLinearGradient(context, paperRect, lightGrayColor, whiteColor);
    draw1PxStroke(context, sepStartPoint, sepEndPoint, separatorColor);

}


// Callee, where the problem is
void drawLinearGradient(CGContextRef context,
                        CGRect rect,
                        CGColorRef startColor, 
                        CGColorRef endColor)
{
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGFloat locations[] = { 0.0, 1.0 };

    NSArray *colors = [NSArray arrayWithObjects:
                       (__bridge id)startColor,
                       (__bridge id)endColor,
                       nil]; // Here is the line

    CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, 
                                                        (__bridge CFArrayRef) colors, locations);

    CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
    CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));

    CGContextSaveGState(context);
    CGContextAddRect(context, rect);
    CGContextClip(context);
    CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
    CGContextRestoreGState(context);

    CGGradientRelease(gradient);
    CGColorSpaceRelease(colorSpace);
}

Xcode突出显示第12行( nil的那一行] ; 作为错误行。

Xcode highlights line 12 (the one with nil]; as the error line.

对于Peter Hosey,这是调试器输出:

For Peter Hosey, here's the debugger output:

(gdb) po startColor
<CGColor 0x1deca0> [<CGColorSpace 0x1d3280> (kCGColorSpaceDeviceGray)] ( 1 1 )
Current language:  auto; currently objective-c
(gdb) po endColor
<CGColorSpace 0x1bf120> (kCGColorSpaceDeviceRGB)
(gbd)

我的模拟器(和iPhone)在iOS 5上运行。

My simulator (and iPhone) runs on iOS 5.

可能导致此次崩溃的原因是什么?

What could be causing this crash?

推荐答案

解决这个问题的一种方法是将UIColors传递给你的函数,而不是CGColorRefs,并使用(id)[color1] CGColor] colors 数组的每个元素进行强制转换。这似乎是人们现在最常用的解决此问题的方法。

One way to work around this would be to pass UIColors into your function, instead of CGColorRefs, and use an (id)[color1 CGColor] cast for each element of your colors array. This appears to be the most popular way that people are addressing this problem right now.

我在这个答案,并在此进行了广泛的讨论此Apple开发者论坛帖子。如果您在声明NSArray时使用UIColor的 -CGColor 方法,并转换为id,则会自动为您桥接所有内容。正如gparker在上面链接的论坛帖子中所述:

I point out one use of this in this answer, and there's extended discussion about this in this Apple developer forum thread. If you use a UIColor's -CGColor method at the point of declaring your NSArray, and cast to id, everything's bridged automatically for you. As gparker states in the above-linked forum thread:


本文档描述的自动案例仅适用于调用目标的
-C方法返回CF类型,然后
立即将结果转换为Objective-C对象类型。如果
使用方法结果执行任何其他操作,例如将其分配给CF类型的
变量,则它不再是自动的。

The automatic case described by the documentation applies only to calling an Objective-C method that returns a CF type and then immediately casting the result to an Objective-C object type. If you do anything else with the method result, such as assign it to a variable of a CF type, then it is no longer automatic.

正如hatfinch指出的那样,这可能意味着放置在临时变量中的CGColorRefs在您最后一次引用UIColors之后不会挂起,除非您明确地保留它们。和那个论坛帖子中的其他人一样,我错误地认为这是桥接实现中的一个错误,但我可以看到我读错了。

As hatfinch points out, this could mean that your CGColorRefs placed in temporary variables won't hang around after the last time you reference your UIColors, unless you explicitly retain them. Like the others in that forum thread, I mistakenly thought this was a bug in the bridging implementation, but I can see that I was reading this wrong.

这篇关于CG Gradient在模拟器上运行,但在iPhone上运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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