这必须非常基础,但我没有看到问题。只要执行以下代码块,程序就会崩溃。 Analyzer报告可能的内存泄漏:
if (anImage) {
eventImageView.frame = defaultEventImageFrame;
UIImage *scaledImage = [anImage scaleToFitWithin:defaultEventImageFrame.size interpolationQuality:kCGInterpolationHigh];
eventImageView.backgroundColor = [UIColor colorWithPatternImage:scaledImage];
}
消息是 - [UIImage release]:发送到解除分配的实例0x1129d920的消息 *
实例0x1129d920是scaledImage
我尝试添加了保留和发布,就像这样
if (anImage) {
eventImageView.frame = defaultEventImageFrame;
UIImage *scaledImage = [[anImage scaleToFitWithin:defaultEventImageFrame.size interpolationQuality:kCGInterpolationHigh] retain];
eventImageView.backgroundColor = [UIColor colorWithPatternImage:scaledImage];
[scaledImage release];
}
仍然收到错误消息。
所以我尝试用副本替换作业,比如
if (anImage) {
eventImageView.frame = defaultEventImageFrame;
UIImage *scaledImage = [anImage copy];
eventImageView.backgroundColor = [UIColor colorWithPatternImage:scaledImage];
}
问题已经消失。
检查scaleToFitWithin方法,我看到它返回一个自动释放的对象:
- (UIImage *) scaleToFitWithin:(CGSize) newSize
interpolationQuality:(CGInterpolationQuality)quality{
CGSize originalImageSize = self.size;
CGSize newImageSize;
if (originalImageSize.width <= originalImageSize.height) {
newImageSize.width = self.size.width * newSize.width / self.size.width;
newImageSize.height = self.size.height * newSize.width / self.size.width;
}
else {
newImageSize.width = self.size.width * newSize.height / self.size.height;
newImageSize.height = self.size.height * newSize.height / self.size.height;
}
return [[[self normalize] resizedImage:newImageSize interpolationQuality:kCGInterpolationHigh] autorelease];
}
所以有一些关于内存管理的东西,我不理解。可能是什么问题?
答案 0 :(得分:1)
问题很可能是scaleToFitWithin:interpolationQuality:
方法在之前已经autorelease
d的对象上调用autorelease
。如果您使用临时构造函数(如UIImage
)初始化+[UIImage imageWith...]
,则可能会出现这种情况,这与您调用缩放方法的方法相同。使用[anImage copy]
时它起作用的原因是因为copy
构造函数的行为使得返回给您的对象已经调用retain
(因此它具有本地保留)计数为1且为零autorelease
s)。
当前运行循环结束时发生的情况是:当前正在使用的自动释放池已耗尽,并且作为这两条release
消息的一部分将被发送到UIImage
。发送第一个应用程序后,应用程序将运行并在图像上调用dealloc
,因为retainCount
已减少到零。当发送第二个时,应用程序抛出异常,因为正在将消息发送到先前已取消分配的对象。
尝试从autorelease
方法中删除scaleToFitWithin:interpolationQuality:
消息。即使您的resizedImage:interpolationQuality:
方法正在返回新对象,您也应该只在该方法中调用autorelease
而不是缩放方法。
答案 1 :(得分:1)
似乎方法resizedImage:interpolationQuality:
本身返回一个autoreleased
对象,您再次在 reutun 语句中自动释放它。只需从 return 语句
return [[self normalize] resizedImage:newImageSize
interpolationQuality:kCGInterpolationHigh];
然后您不必在if (anImage) {...}
块中保留/释放或复制返回的对象。