0

У меня здесь интересная загадка. Мой проект cocos2d использует UIView для отображения более привлекательных всплывающих окон, чем обычный просмотр предупреждений. Чтобы быть более гибким по размеру всплывающего окна, я рисую фон в методе drawRect.CoreGraphics drawRect в проекте cocos2d EXEC BAD ACCESS

Но первая иерархия, как я реализую cocos2d и UIKit: Hierarchy

Каждый UIKit элемент добавляется в RootViewController. Каждый CCNode для EAGLView. (Если у кого-то есть лучшее решение, чтобы смешать этот мир, не ждите, чтобы рассказать мне!) К сожалению, каждый UIKit вид перед узлами кокоса.

Все работает нормально, когда я добавляю первое всплывающее окно к RootViewController. Но если я удалю первое всплывающее окно и добавлю новый в RootViewController, произойдет плохой доступ. Он падает только в сочетании с cocos2d.

Я использую код из учебника Ray Wenderlichs CoreGraphics 101. The crash

контекст и strokeColor не ноль. Другая важная информация: я использую ARC и поддерживаю iOS 4.2 и выше.

Полный код можно найти на raywenderlich.com или ниже

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]; 

    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); 
} 

CGRect rectFor1PxStroke(CGRect rect) 
{ 
    return CGRectMake(rect.origin.x + 0.5, rect.origin.y + 0.5, rect.size.width - 1, rect.size.height -1); 
} 

- (void)drawRect:(CGRect)rect 
{ 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGRect frame = CGRectInset(self.bounds, 2, 2); 

    CGContextSetShadowWithColor(context, CGSizeMake(0, 0), 3.0, shadowColor); 

    CGRect strokeRect = CGRectInset(frame, -2.0, -2.0); 
    CGContextSetStrokeColorWithColor(context, strokeColor); 
    CGContextSetLineWidth(context, 2.0); 
    CGContextStrokeRect(context, rectFor1PxStroke(strokeRect)); 
    drawLinearGradient(context, frame, gradient1, gradient2); 
} 
+0

Этот ответ решает эту проблему: http://stackoverflow.com/questions/9963530/app-crashes-when-using-bridge-for-coregraphics-gradient-on-arc – zeiteisen

+0

zeiteisen ......... проверить этот форум http://www.cocos2d-iphone.org/forum/topic/6889 там обертка для загрузки представлений UIKit сверху (как вы хотите иерархию представлений) EAGLView. – Ankur

ответ

2

ARC выпускает CGColorRef под названием strokeColor. Одним из способов исправить это, чтобы заменить его с массивом CGFloat и использовать CGContextSetStrokeColor вместо CGContextSetStrokeColorWithColor

Этот ответ решает этот вопрос: App crashes when using __bridge for CoreGraphics gradient on ARC

0

Я согласен с zeiteisen, ARC выпускает CGColorRef и самый простой способ решить эту проблему с помощью

  • замена CGContextSetStrokeColorWithColor с CGContextSetStrokeColor (контекст, компоненты)
  • Изменить UIColor из strokeColor в 'компоненты RGB CGFloat массива' следующим образом:

    static CGFloat red, green, blue, alpha; 
    
    - (void)getRGBComponents:(CGFloat [4])components forColor:(UIColor *)color { 
    
        [color getRed:&red green:&green blue:&blue alpha:&alpha];//To fetch CGFloat RGB components 
    
        for (int component = 0; component < 4; component++) {  
         switch (component) { 
          case 0: 
           components[component] = red; 
           break; 
          case 1: 
           components[component] = green; 
           break; 
          case 2: 
           components[component] = blue; 
           break; 
          case 3: 
           components[component] = alpha; 
           break; 
          default: 
           break; 
        } 
    } 
    

    }

Используйте этот метод, как это:

CGFloat components[4]; 
UIColor *strokeColor=[UIColor greyColor];//My color 
[self getRGBComponents:components forColor:strokeColor];//'components' will be substituted in CGContextSetStrokeColor 
NSLog(@"%f %f %f %f", components[0], components[1], components[2],components[3]);