我有一个基于一系列图层生成图像的视图。我有背景图像,缩略图图像,最后是叠加图像。它共同构成了一个有凝聚力的展示。
它似乎是一个梦想,除非它没有。由于看似没有理由,我在下面的指定行上得到一个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;
}
}
我无法找到任何错误的地方,而且我已经把头发撕了几个小时了。这是系统中最后已知的错误,所以你可以想象我是多么难以修复它! : - )
提前感谢您的帮助。
答案 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)
事实证明,错误不在我发布的代码中,而是在我对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];
}
}
我会承认我仍然对目标C中的整个保留/释放/自动释放内容感到不舒服。希望它很快会在一天之内下沉。 : - )