Цель C: EXC_BAD_ACCESS при создании UIImage - PullRequest
0 голосов
/ 26 августа 2010

У меня есть вид, который генерирует изображение на основе ряда слоев.У меня есть изображения для фона, миниатюры и, наконец, для наложения.Вместе он создает единый дисплей.

Кажется, что это работает мечтой, за исключением случаев, когда это не так.По-видимому, без причины я получаю EXC_BAD_ACCESS в указанной строке ниже после того, как она сгенерирована где-то между 8 и 20 изображениями.Я провел его через инструмент утечки памяти и инструмент выделения, и он не поглощает тонны памяти и не протекает.Я в полном замешательстве.

Вот соответствующий код:

- (UIImage *)addLayer:(UIImage *)layer toImage:(UIImage *)background atPoint:(CGPoint)point {
  CGSize size = CGSizeMake(240, 240);
  UIGraphicsBeginImageContext(size);

  [background drawAtPoint:CGPointMake(0, 0)];  // <--- error here
  [layer drawAtPoint:point];

  UIImage* result = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();

  return result;
}


// Build the layered image -- thingPage onto thingBackground,
// then the screenshot on that, then the thingTop on top of it all.
// thingBackground, thingPage and thingTop are all preloaded UIImages.
-(UIImage *)getImageForThing:(Thing *)t {
  [self loadImageCacheIfNecessary];

  if (!t.screenshot) {
    return [UIImage imageNamed:@"NoPreview.png"];
  } else {
    UIImage *screenshot = t.screenshot;
    UIImage *currentImage = [self addLayer:thingPage toImage:thingBackground atPoint:CGPointMake(0, 0)];
    currentImage = [self addLayer:screenshot toImage:currentImage atPoint:CGPointMake(39, 59)];
    currentImage = [self addLayer:thingTop toImage:currentImage atPoint:CGPointMake(0, 1)]; 

    return currentImage;
  }
}

Я нигде не могу найти, что это идет не так, и я рвал на себе волосы на паручасов на это.Это последняя известная ошибка в системе, так что вы можете себе представить, как я могу ее исправить!: -)

Заранее спасибо за любую помощь.

Ответы [ 3 ]

0 голосов
/ 26 августа 2010

EXC_BAD_ACCESS почти всегда из-за доступа к объекту, который уже был освобожден. В вашем коде это похоже на t.screenshot. Проверьте создание (и сохранение, если это переменная экземпляра) объекта, возвращенного свойством Thing screenshot.

0 голосов
/ 26 августа 2010

Как оказалось, ошибка была не в коде, который я выложил, а в моем кешировании изображений thingBackground, thingPage и thingTop. Я не удерживал их. Вот отсутствующий код, исправленный:

-(void)loadImageCacheIfNecessary {
  if (!folderBackground) {
    thingBackground = [[UIImage imageNamed:@"ThingBack.png"] retain];
  }
  if (!folderPage) {
    thingPage = [[UIImage imageNamed:@"ThingPage.png"] retain];
  }
  if (!folderTop) {
    thingTop = [[UIImage imageNamed:@"ThingTop.png"] retain];
  }
}

Я признаю, что мне все еще не нравится весь материал retain / release / autorelease в Objective C. Надеюсь, это скоро пройдет. : -)

0 голосов
/ 26 августа 2010

Что касается меня, я всегда использую - (void) drawInRect: вместо - (void) drawAtPoint:

<code>
CGRect rtDraw;
rtDraw.origin = CGPointZero;
rtDraw.size = size;
[background drawInRect:rtDraw];
[layer drawInRect:rtDraw];

и .... метод рисованияс UIGraphicsBeginImageContext (size) и UIGraphicsEndImageContext () не является поточно-ориентированным.Эти функции будут выдвигать или выталкивать контекст со структурой стека, которой управляет система.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...