Objective c CGContextDrawImage-EXC_BAD_访问和地图覆盖渲染器
我有一张地图。有时,我在Objective c CGContextDrawImage-EXC_BAD_访问和地图覆盖渲染器,objective-c,exc-bad-access,Objective C,Exc Bad Access,我有一张地图。有时,我在CGContextDrawImage 我的图像设置器设置覆盖图像的方法 -(void)SetImageRef:(CGImageRef)imageRef { CGImageRelease(_imageReference); _imageReference = CGImageCreateCopy(imageRef); } 我的画法 - (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZ
CGContextDrawImage
我的图像设置器设置覆盖图像的方法
-(void)SetImageRef:(CGImageRef)imageRef
{
CGImageRelease(_imageReference);
_imageReference = CGImageCreateCopy(imageRef);
}
我的画法
- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context
{
MKMapRect theMapRect = self.overlay.boundingMapRect;
CGRect theRect = [self rectForMapRect:theMapRect];
CGContextSetInterpolationQuality(context, self.interpolation);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextTranslateCTM(context, 0.0, -theRect.size.height);
CGContextDrawImage(context, theRect, _imageReference); //<---- EXC_BAD_ACCESS
}
-(void)drawMapRect:(mkmapret)mapret zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context
{
MKMapRect theMapRect=self.overlay.boundingMapRect;
cRect theRect=[自校正:TheMarect];
CGContextSetInterpolationQuality(上下文,self.interpolation);
CGContextScaleCTM(上下文,1.0,-1.0);
CgContextTranslateCm(上下文,0.0,-theRect.size.height);
CGContextDrawImage(上下文、上下文、图像引用);//我怀疑您有时会将当前的\u imageReference
传递给SetImageRef:
。您的SetImageRef
实现无法安全地处理这种情况。当您使用CGImageRelease
释放\u imageReference
时,它将被释放(除非有其他东西在保留\u imageReference
,但听起来好像不是这样)。如果您使用以下工具进行复制:
_imageReference = CGImageCreateCopy(imageRef);
碰巧,imageRef==\u imageReference
然后会发生什么?你最终得到的是一个僵尸(或即将成为僵尸)图像的副本。现在,你正在制作一个副本,所以你可能会认为,imageRef
是否死亡无关紧要(只要它在发布后没有立即被覆盖,尽管这仍然是不安全的代码),但有一个陷阱。CGImageCreateCopy
的文档说明:
仅复制图像结构本身;复制
基础数据不可用
因此,\u imageReference
的“图像结构”数据可能是安全的,但是\u imageReference
实际生成像素所需的数据是不安全的。这就是为什么最终尝试使用CGContextDrawImage
渲染图像时会出现问题的原因
这是一种非常冗长的说法,表示您需要对SetImageRef
更加小心。我建议您在imageRef==\u imageReference
的特殊情况下尽早返回:
-(void)SetImageRef:(CGImageRef)imageRef {
if (imageRef == _imageReference) {
return;
}
CGImageRelease(_imageReference);
_imageReference = CGImageCreateCopy(imageRef);
}
我为OS X开发了颜色选择器,在使用两个物理显示器时遇到了相同的问题。请尝试将您的自定义“setImageRef”写为:
Aaron Golden对此问题有更详细的描述。这不是问题所在Aaron,这解决了我的问题,但出现了相同的错误。感谢您发布。@MartinPerry如果这不是问题所在,您是否以其他方式解决了它?如果您这样做,您应该将其发布在此处。
//Fix CGContextDrawImage Crash
-(void)SetImageRef:(CGImageRef)imgRef
{
if (imgRef == _imageRef) return;
CGImageRelease(_imageRef);
_imageRef = CGImageCreateCopy(imgRef);
}