目标C:生成UIImage时的EXC_BAD_ACCESS

时间:2010-08-25 22:23:09

标签: iphone objective-c ipad uiimage

我有一个基于一系列图层生成图像的视图。我有背景图像,缩略图图像,最后是叠加图像。它共同构成了一个有凝聚力的展示。

它似乎是一个梦想,除非它没有。由于看似没有理由,我在下面的指定行上得到一个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 :(得分:0)

至于我,我总是使用 - (void)drawInRect:而不是 - (void)drawAtPoint:


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

并...... 使用UIGraphicsBeginImageContext(size)和UIGraphicsEndImageContext()的paint方法不是线程安全的。 这些函数将使用由系统管理的堆栈结构推送或弹出上下文。

答案 1 :(得分:0)

EXC_BAD_ACCESS几乎总是由于访问已经发布的对象。在您的代码中,这似乎是t.screenshot。检查Thing的{​​{1}}属性返回的对象的创建(并保留它是否为实例变量)。

答案 2 :(得分:0)

事实证明,错误不在我发布的代码中,而是在我对thingBackgroundthingPagethingTop图像的缓存中。我没有留住他们。这是缺失的代码,已修复:

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

我会承认我仍然对目标C中的整个保留/释放/自动释放内容感到不舒服。希望它很快会在一天之内下沉。 : - )