Хобрук: Ваш путь к мастерству в программировании

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

Я пытаюсь добавить тень к своему 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;

to

компоненты с плавающей запятой [4] = {0, 0, 0, 1.0 / 3.0}; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB (); CGColorRef shadowColor = CGColorCreate (цветовое пространство, компоненты);

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

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

  • Опубликуйте точное сообщение об ошибке здесь. 23.01.2012
  • Сообщение об ошибке на самом деле не поможет, но для вашего удобства (см. Правка). 23.01.2012
  • Ваш отладчик должен хотя бы сказать вам, в какой строке происходит сбой. 23.01.2012
  • drawRect вызывается самой iOS при отрисовке UIView. 23.01.2012
  • Вылетает на CGContextSetFillColorWithColor 23.01.2012
  • Можете ли вы попробовать CGColorRetain() вокруг ваших [UIColor ...].CGColor строк? CGColorRef shadowColor = CGColorRetain([UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:0.4].CGColor); просто для того, чтобы убедиться, что цвета сохранены (возможно, чрезмерно). 23.01.2012
  • В противном случае: UIColor *shadowUIColor = [UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:0.4];, а затем для слоев используйте shadowUIColor.CGColor напрямую. 23.01.2012

Ответы:


1

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

[[UIColor colorWithRed:105.0f/255.0f green:179.0f/255.0f blue:216.0f/255.0f alpha:0.8] setFill];
23.01.2012
  • теперь он вылетает на CGContextSetShadowWithColor (context, CGSizeMake (-5, 0), 10, shadowColor); 23.01.2012
  • А что будет, если убрать эту строчку? 23.01.2012
  • Что если вы создадите свой цвет тени с помощью одного из методов CGColorCreate ... и отпустите его после рисования. Это не должно быть обязательно, и это больше хлопот, но опять же, это должно помочь диагностировать, действительно ли проблема связана с этой линией. 23.01.2012
  • К вашему сведению, этот цвет тени теперь просачивается. Вы должны вызвать CGColorRelease (shadowColor); после того, как вы закончите с этим. 03.07.2012
  • Я так не думаю. ARC вставляет для вас операторы [... release] и [... autorelease] в стиле какао, но он не знает, как очистить объекты Core Foundation, поэтому объекты, созданные с помощью XXCreate ... по-прежнему должны быть выпущены с помощью XXRelease когда вы закончите с ними. Вы также пропускаете CGColorSpaceRef. 13.07.2012

  • 2

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

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

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

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

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

    23.01.2012
  • Надеюсь нет! Если так, это было бы ужасной ошибкой с ARC. 23.01.2012
  • @Nick, да, переход ARC может сломать большой объем кода, но вот как это работает. 23.01.2012
  • Табличное представление Three20 также дает сбой, начиная с iOS 5 с включенной теневой настройкой. 24.01.2012
  • @ mc007 Кто-нибудь придумал этому объяснение? 24.01.2012
  • Идет обсуждение, но извините, я не могу вспомнить, где, да у меня не было времени найти его обратно. 24.01.2012

  • 3

    В качестве альтернативы вы можете указать компилятору добавить ваши 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;   
    
    23.02.2012

    4

    Приведенный ниже код удовлетворяет требованиям 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 * сразу после его создания.

    29.12.2012
    Новые материалы

    Как свинг-трейдеры могут использовать ИИ для больших выигрышей
    По мере того как все больше и больше профессиональных трейдеров и активных розничных трейдеров узнают о возможностях, которые предоставляет искусственный интеллект и машинное обучение для улучшения..

    Как построить любой стол
    Я разработчик программного обеспечения. Я люблю делать вещи и всегда любил. Для меня программирование всегда было способом создавать вещи, используя только компьютер и мое воображение...

    Обзор: Машинное обучение: классификация
    Только что закончил третий курс курса 4 часть специализации по машинному обучению . Как и второй курс, он был посвящен низкоуровневой работе алгоритмов машинного обучения. Что касается..

    Разработка расширений Qlik Sense с qExt
    Использование современных инструментов веб-разработки для разработки крутых расширений Вы когда-нибудь хотели кнопку для установки переменной в приложении Qlik Sense? Когда-нибудь просили..

    React Hooks: основы деструктуризации массива
    Kent C. Dodds написал классный пост о том, как грядущая функция React под названием Hooks работает на капоте. Предстоящий хук React useState основан на деструктурировании массива, давайте..

    Пакеты R, используемые в Tesla
    Добро пожаловать обратно! R — очень популярный язык программирования, используемый множеством компаний, включая Tesla! Итак, давайте взглянем на некоторые пакеты R, которые использует Tesla...

    Сокращение и слияние токенов для эффективных моделей VL: обзор
    Часто в задачах, связанных с компьютерным зрением и НЛП, вычислительно затратная и требующая большого объема памяти обработка становится препятствием для более быстрого логического вывода модели, а..