Ошибка CGContextSetFillColorWithColor (EXC_BAD_ACCESS)

Я смущен, почему мое приложение падает с этой ошибкой.

Я реализовал метод displayLayer (для рендеринга CALayer). При первом запуске этого метода все работает нормально. Но при последующих обращениях к этому возникает ошибка.

Ошибка возникает, когда для self.bgColor устанавливается цвет заливки контекста. ИНТЕРЕСНО... если я создаю bgColor прямо перед этой строкой, все работает. Но в нынешнем виде bgColor создается при инициализации этого класса (контейнера метода displayLayer).

-(void)displayLayer:(CALayer *)caLayer
{
  UIGraphicsBeginImageContext(caLayer.frame.size);
  CGContextRef context = UIGraphicsGetCurrentContext();    
  CGContextSetFillColorWithColor(context, self.bgColor);
  CGContextFillRect(context, CGRectMake(0, 0, 320, 25)); 
  [self drawText:context];
  // get image buffer
  UIImage *imageBuffer = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();
  // set layer contents to image buffer
  caLayer.contents = (id)[imageBuffer CGImage];
}

person AlvinfromDiaspar    schedule 28.09.2009    source источник
comment
Боже мой, извините за скомканный фрагмент кода!!   -  person AlvinfromDiaspar    schedule 28.09.2009
comment
Чтобы отформатировать код, используйте четыре пробела в начале каждой строки или используйте кнопку с цифрами 1 и 0, которая сделает это за вас.   -  person 1800 INFORMATION    schedule 28.09.2009
comment
Как вы настраиваете bgColor? Не могли бы вы опубликовать этот фрагмент кода? Я подозреваю, что вы не сохраняете его и используете автоматически выпущенный цвет. Первый раз displayLayer вызывается, вероятно, в том же цикле выполнения, поэтому цвет еще не выпущен. Затем цикл выполнения завершается, bgColor освобождается, а при последующих вызовах displayLayer: вы получаете ошибку EXC_BAD_ACCESS.   -  person Thomas Müller    schedule 28.09.2009
comment
в моем заголовочном файле есть эта строка CGColorRef bgColor; Изначально я не создавал свойство для этого. Затем я решил дать ему свойство... @property (nonatomic) CGColorRef bgColor; Обратите внимание, что ему нравится, когда это свойство определяется как сохранение, поскольку оно не является типом объекта.   -  person AlvinfromDiaspar    schedule 28.09.2009
comment
И в методе инициализации моего класса я присваиваю значение для bgColor... bgColor = [[UIColor blackColor] CGColor];   -  person AlvinfromDiaspar    schedule 28.09.2009


Ответы (1)


Я еще мало занимался программированием для iPhone и никогда не использовал переменную экземпляра CGColor, поэтому я бы сделал следующее:

@interface {
    ....
    UIColor *bgColor;
    ....
}
@property (nonatomic, retain) UIColor *bgColor;
...
@end

@implementation
@synthesize bgColor;
- (id)init {
    ...
    self.bgColor = [UIColor blackColor];
    ...
}
-(void)displayLayer:(CALayer *)caLayer {
    ...
    CGContextSetFillColorWithColor(context, self.bgColor.CGColor);
    ...
}
...
@end

[UIColor blackColor] возвращает автоматически выпущенный объект, и вы присвоили его переменной экземпляра, не сохраняя его.

Использование self.bgColor вместо простого bgColor в init и настройка свойства для сохранения его значения гарантирует, что цвет будет сохранен и может быть использован в displayLayer позже.

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

person Thomas Müller    schedule 28.09.2009
comment
Хммм... вся эта связь между собой и неиспользованием себя, по-видимому, не совсем устоялась в моем сознании. Но то, что вы только что сказали, имеет для меня смысл. Я уже настроился на использование UIColor* вместо CGColor. Спасибо за помощь. - person AlvinfromDiaspar; 28.09.2009
comment
Synthese bcColor сгенерирует два метода: -(UIColor *)bgColor и -(void)setBgColor:(UIColor *)aColor;. Эти методы обрабатывают сохранение и освобождение объектов. Использование self.bgColor = xxx эквивалентно вызову [self setBgColor:xxx], а использование xxx = self.bgColor эквивалентно вызову xxx=[self bgColor], поэтому обо всем сохранении и освобождении заботятся. Если вы напрямую читаете или изменяете переменную экземпляра (без себя), вам придется сохранять и освобождать себя. - person Thomas Müller; 28.09.2009
comment
Лучшее место в этом ответе - использование self.bgColor.CGColor для получения значения CGColorRef для UIColor IMHO. - person HCdev; 09.01.2013
comment
@Thomas Müller Спасибо, Томас. Я рву на себе волосы из-за этого. Оказалось, что я неправильно установил атрибуты сходства свойства. \@property (неатомарное, присваиваемое) UIColor *bgColor; -> \@property (неатомарное, сохраняемое) UIColor *bgColor; решил это. Я никогда не знал, что эти атрибуты имеют такое большое значение... - person Charles Robertson; 26.11.2016