DCRoundSwitch выдает EXC_BAD_ACCESS при использовании ARC - PullRequest
9 голосов
/ 10 декабря 2011

Я использую DCRoundSwitch для проекта, где мне в основном нужен UISwitch, где я могу редактировать содержимое его ярлыка.

Поскольку я использую ARC, я реорганизовал код DCRoundSwitch, чтобы он был ARC -совместимым в xcode.

При компиляции и запуске в симуляторе он работает без проблем.

Тем не менее, при работе на устройстве это дает мне EXC_BAD_ACCESS возле линии 57 DCRoundSwitchKnobLayer.m

На GitHub есть сообщение об ошибке , но решение пока не найдено.

Вот код, который дает 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 ]

9 голосов
/ 15 августа 2012

У меня была такая же проблема, и я действительно хотел преобразовать код в ARC. Сбой происходит, потому что startColor и endColor уже освобождены, когда вызывается CreateGradientRefWithColors.

Вот мое исправление:

- (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/

7 голосов
/ 10 декабря 2011

EDIT

Извинения, правильное исправление для этого кода с 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.

Все, что вы хотели знать об ARC , содержит несколько руководств по этому поводу. ARC Q & A также имеет несколько хороших руководств по этому вопросу.

5 голосов
/ 10 декабря 2011

colorsArray высвобождается с использованием метода CFRelease.ARC не позволяет использовать retain и release, так почему бы вам не попробовать закомментировать строку CFRelease(colorsArray) и посмотреть, предотвращает ли это ошибку?

Edit--

Этот ответ был принят, поскольку он предоставил действительное исправление проблемы ОП, отключив ARC.

Если вы не хотите использовать этот метод, см. Ответ @ petesh.

...