我知道在 StackOverflow 上有很多关于这个主题的问题,我希望尝试了很多提示和答案。但在这个非常简单的案例中没有任何帮助。
--
在基于 ARC 的应用程序中,我使用来自 Ray Wunderlich 的名为 SpeechBubbleView 的 UIView 子类。它是 UIView 的子类,用于绘制一个包含文本的语音气泡,就像在 SMS-Message-App 中一样。
它使用 UIImage 的两个实例。在 View 的 drawRect-Method 中绘制气泡。
在 iPhone 模拟器中一切正常。但是 iPhone 5 运行 iOS 7.1 时总是会出现 EXC_BAD_ACCESS 异常 每次第二张图片 被绘制,无论是否绘制了第一张图像。
我将提供一些代码:
@property (nonatomic, retain) UIImage* lefthandImage;
@property (nonatomic, retain) UIImage* righthandImage;
在 initWithFrame-Method 从支持的文件夹中加载的两个图像:
self.lefthandImage = [[UIImage imageNamed:@"BubbleLefthand"]
stretchableImageWithLeftCapWidth:20 topCapHeight:19];
self.righthandImage = [[UIImage imageNamed:@"BubbleRighthand"]
stretchableImageWithLeftCapWidth:20 topCapHeight:19];
在 SpeechBubbleView 的 drawRect 方法中,图像被绘制:
- (void)drawRect:(CGRect)rect
{
[self.backgroundColor setFill];
UIRectFill(rect);
CGRect bubbleRect = CGRectInset(self.bounds, VertPadding, HorzPadding);
CGRect textRect;
textRect.origin.y = bubbleRect.origin.y + TextTopMargin;
textRect.size.width = bubbleRect.size.width - TextLeftMargin - TextRightMargin;
textRect.size.height = bubbleRect.size.height - TextTopMargin - TextBottomMargin;
if (_bubbleType == BubbleTypeLefthand)
{
[self.lefthandImage drawInRect:bubbleRect];
textRect.origin.x = bubbleRect.origin.x + TextLeftMargin;
}
else
{
[self.righthandImage drawInRect:bubbleRect];
textRect.origin.x = bubbleRect.origin.x + TextRightMargin;
}
[[UIColor blackColor] set];
NSMutableParagraphStyle *textStyle = [[NSMutableParagraphStyle defaultParagraphStyle] mutableCopy];
textStyle.lineBreakMode = NSLineBreakByWordWrapping;
textStyle.alignment = NSTextAlignmentLeft;
[_text drawInRect:textRect withAttributes:@{NSFontAttributeName:font, NSParagraphStyleAttributeName:textStyle}];
}
在将绘制“RightHandImage”的代码行处,每次抛出 BAD_ACCESS-Exception。如果我将此行注释掉,一切正常。左手气泡将完美地绘制为“气泡”。
此外,如果我注释掉绘制第一个图像(左手气泡)的行,第二个图像将引发此异常。
即使现在已经实现了多线程,我也尝试将 draw-Methods 封装在 中。 @synthesize(...){...} 在 StackOverflow 上对类似问题进行了一些提示,但这不是解决方案,并且每次仍然抛出异常。
我知道没有其他类持有此图像的实例以输入访问权限问题。
谁能给我一些提示,现在该做什么?谢谢!
编辑:UITableViewCell-Hint 并真正创建自己的图像副本
也许很高兴知道 SpeechBubbleView 的每个 Instance 都是在一个重用的 UITableViewCell 中绘制的。因此,我不再使用 UIImage:imageNamed 返回的 UIImage-Instances,而是使用以下代码创建每个的真正副本:
UIImage* tmpImage = [UIImage imageNamed:@"BubbleLefthand"];
self.lefthandImage = [[UIImage imageWithCGImage:[tmpImage CGImage] ]
stretchableImageWithLeftCapWidth:20 topCapHeight:19];
tmpImage = [UIImage imageNamed:@"BubbleRighthand"];
self.righthandImage = [[UIImage imageWithCGImage:[tmpImage CGImage] ]
stretchableImageWithLeftCapWidth:20 topCapHeight:19];
而且,针对 Putz1103 建议,我在 draw-Methods 周围添加了 nil-guards:
if (_bubbleType == BubbleTypeLefthand)
{
if(self.lefthandImage != nil) {
[self.lefthandImage drawInRect:bubbleRect];
}
textRect.origin.x = bubbleRect.origin.x + TextLeftMargin;
}
else
{
if(self.righthandImage != nil) {
[self.righthandImage drawInRect:bubbleRect];
}
textRect.origin.x = bubbleRect.origin.x + TextRightMargin;
}
它仍然在 iPhone 上崩溃,它只适用于 iPhone-Simulator。
编辑 2:用 Rect 绘制的东西
它与矩形有关。如果我将 bubbleRect 更改为从 0/0 开始的 Rect,宽度和高度各为 10 像素,则异常为 未抛出 .
如果我使用更大尺寸的矩形,则会发生异常。因此,该区域似乎受到其他保护
最佳答案
将中间的代码更改为
if (_bubbleType == BubbleTypeLefthand)
{
if(self.lefthandImage != nil)
[self.lefthandImage drawInRect:bubbleRect];
textRect.origin.x = bubbleRect.origin.x + TextLeftMargin;
}
else
{
if(self.righthandImage != nil)
[self.righthandImage drawInRect:bubbleRect];
textRect.origin.x = bubbleRect.origin.x + TextRightMargin;
}
然后看看它是否仍然崩溃。如果没有(不应该),您知道这是因为图像由于某种原因无法加载。确保您正在加载的文件名是 与您在项目中包含的大小写正确的大小写 在项目属性的“构建阶段”部分中。
关于iOS:UIImage 上的 EXC_BAD_ACCESS:drawInRect 有 2 个图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23434904/