使用ARC时,DCRoundSwitch提供EXC_BAD_ACCESS

时间:2011-12-10 15:12:40

标签: objective-c cocoa-touch ios5 exc-bad-access automatic-ref-counting

我正在使用DCRoundSwitch进行项目,我基本上需要一个UISwitch,我可以编辑其标签内容。

因为我正在使用ARC我将DCRoundSwitch代码重构为ARC - 在xcode中兼容。

在模拟器中编译和运行时,它没有任何问题。

但是,在设备上运行时,它会在EXC_BAD_ACCESS

的第57行附近DCRoundSwitchKnobLayer.m给我

GitHub上有bug report但尚未找到解决方案。

以下是提供EXC_BAD_ACCESS的代码:

CGGradientRef CreateGradientRefWithColors(CGColorSpaceRef colorSpace, CGColorRef startColor, CGColorRef endColor)
{
    CGFloat colorStops[2] = {0.0, 1.0};
    CGColorRef colors[] = {startColor, endColor};

    //THIS LINE BREAKS THE PROGRAM
    CFArrayRef colorsArray = CFArrayCreate(NULL, (const void**)colors, sizeof(colors) / sizeof(CGColorRef), &kCFTypeArrayCallBacks); 

    CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, colorsArray, colorStops);
    CFRelease(colorsArray);
    return gradient;
}

任何线索都会受到赞赏。

编辑:以下是来自xcode的本地变量:

enter image description here

3 个答案:

答案 0 :(得分:9)

我有同样的问题,我真的想将代码转换为ARC。 发生崩溃是因为在调用CreateGradientRefWithColors时已经释放了startColor和endColor。

这是我的修复:

- (void)drawInContext:(CGContextRef)context
{
    UIColor *startColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0];
    UIColor *endColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];

    NSArray *colors = [NSArray arrayWithObjects:(__bridge id)startColor.CGColor, (__bridge id) endColor.CGColor, nil];

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

这篇文章有助于找到解决方案:http://www.bobmccune.com/2012/02/28/a-funny-thing-happened-on-the-way-to-the-arc/

答案 1 :(得分:7)

修改

道歉,使用ARC对此代码的正确修复是:

CGGradientRef CreateGradientRefWithColors(CGColorSpaceRef colorSpace, CGColorRef startColor, CGColorRef endColor)
{
    CGFloat colorStops[2] = {0.0, 1.0};
    NSArray *colors = [NSArray arrayWithObjects:(id)startColor, (id)endColor, nil];

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

    return gradient;
}

您使用颜色的NSArray进行桥接转换,而不是进行创建CFArrayRef的额外工作。这次重构是在Core Graphics 101的讨论中无耻地被盗的。这是Objective-C上一个令人敬畏的turorial网站。

Everything you wanted to know about ARC有一些关于此的指南。 ARC Q&A也有一些很好的指导。

答案 2 :(得分:5)

colorsArray使用方法CFRelease发布。 ARC不允许使用retainrelease,那么为什么不尝试评论一行CFRelease(colorsArray)并查看是否可以防止错误?

编辑 -

这个答案被接受了,因为它通过禁用ARC提供了OP问题的有效修复。

如果您不想使用此方法,请参阅@ petesh的答案。