EXC_BAD_ACCES рисование тени - PullRequest
       15

EXC_BAD_ACCES рисование тени

3 голосов
/ 23 января 2012

Я пытаюсь добавить тень к своему UIView, но в моем методе drawRect я получаю EXC_BAD_ACCESS.(Я использую ARC)

-(void) drawRect:(CGRect)rect {

    CGColorRef lightColor =  [UIColor colorWithRed:105.0f/255.0f green:179.0f/255.0f blue:216.0f/255.0f alpha:0.8].CGColor;

    CGColorRef shadowColor = [UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:0.4].CGColor;   

    CGContextRef context = UIGraphicsGetCurrentContext();
    // Draw shadow
    CGContextSaveGState(context);
    CGContextSetShadowWithColor(context, CGSizeMake(-5, 0), 10, shadowColor);
    CGContextSetFillColorWithColor(context, lightColor);
    CGContextFillRect(context, _coloredBoxRect);
    CGContextRestoreGState(context);
}

Сообщение об ошибке: Поток 1: Программа получила сигнал: "EXC_BAD_ACCESS".

Строка: CGContextSetFillColorWithColor(context, lightColor);

Когда я изменяю эту строку на:

[[UIColor colorWithRed:105.0f/255.0f green:179.0f/255.0f blue:216.0f/255.0f alpha:0.8] setFill];

Я получаю ту же ошибку, но в этой строке:

CGContextSetShadowWithColor(context, CGSizeMake(-5, 0), 10, shadowColor);

Обновление Я наконец решил проблему, изменив:

CGColorRef shadowColor = [UIColor colorWithRed: 0,2 зеленый: 0,2 синий: 0,2 альфа: 0,4] .CGColor;

до

поплавковые компоненты [4] = {0, 0, 0, 1.0 / 3.0};CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB ();CGColorRef shadowColor = CGColorCreate (colorSpace, компоненты);

Возможный (рабочий) код:

-(void) drawRect:(CGRect)rect 
{
    float components[4] = {0, 0, 0, 1.0/3.0};
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGColorRef shadowColor = CGColorCreate( colorSpace, components);

    CGContextRef context = UIGraphicsGetCurrentContext();

    // Draw shadow
    CGContextSaveGState(context);
    CGContextSetShadowWithColor(context, CGSizeMake(-5, 0), 10, shadowColor);
    CGContextSetFillColorWithColor(context, lightColor);

    [[UIColor colorWithRed:105.0f/255.0f green:179.0f/255.0f blue:216.0f/255.0f alpha:0.8] setFill];

    CGContextRestoreGState(context);
}

Ответы [ 4 ]

5 голосов
/ 23 января 2012

UIColor может не превратиться в пул автоматического выпуска, если включена ARC. Если он не помещен в пул и сразу не выпущен, то ссылка CGColor, на которую вы ссылаетесь (lightColor, shadowColor), также была бы освобождена к тому времени, когда вы ее передали, потому что они принадлежат UIColor, и никакие меры было сделано для того, чтобы эти (не NSObject) ссылки оставались действительными за пределами этой области.

Я не могу воспроизвести вашу точную проблему, но я могу воспроизвести ее, используя:

CGColorRef shadowColor =
  [[UIColor alloc] initWithRed:0.2 green:0.2 blue:0.2 alpha:0.4].CGColor;

при запуске на сим v5.0.

Вы опубликовали точный пример? На какой версии ОС вы работаете? Это происходит во всех версиях ОС? Возможно, вам стоит взглянуть на асм.

3 голосов
/ 23 февраля 2012

В качестве альтернативы вы можете указать компилятору добавить ваши UIColor объекты в пул автоматического выпуска, а не немедленно освобождать их.

UIColor * __autoreleasing lightUIColor = [UIColor colorWithRed:105.0f/255.0f green:179.0f/255.0f blue:216.0f/255.0f alpha:0.8];
CGColorRef lightColor =  lightUIColor.CGColor;

UIColor * __autoreleasing shadowUIColor = [UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:0.4];
CGColorRef shadowColor = shadowUIColor.CGColor;   
2 голосов
/ 23 января 2012

Я не вижу причин, по которым это может произойти сбой, но попробуйте установить свой цвет, используя этот код, а не CGColorRef.Если это не устранит проблему, по крайней мере, вы будете знать, что проблема не в этой строке:

[[UIColor colorWithRed:105.0f/255.0f green:179.0f/255.0f blue:216.0f/255.0f alpha:0.8] setFill];
0 голосов
/ 29 декабря 2012

Приведенный ниже код удовлетворит ARC:

UIColor *lightColor =  [UIColor colorWithRed:105.0f/255.0f green:179.0f/255.0f blue:216.0f/255.0f alpha:0.8];
...
CGContextSetFillColorWithColor(context, lightColor.CGColor);

Причина сбоя в том, что ARC освободил временный объект UIColor * сразу после его создания.

...