发送到已释放实例的消息——简短
这必须是非常基本的,但我没有看到问题。每当执行以下代码块时,程序就会崩溃。分析器报告可能的内存泄漏:
if (anImage) {
eventImageView.frame = defaultEventImageFrame;
UIImage *scaledImage = [anImage scaleToFitWithin:defaultEventImageFrame.size interpolationQuality:kCGInterpolationHigh];
eventImageView.backgroundColor = [UIColor colorWithPatternImage:scaledImage];
}
消息为 -[UIImage release]:消息发送到已释放实例0x1129d920*
实例0x1129d920已缩放图像
我尝试过像这样添加保留和释放,
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];
}
所以我不理解内存管理的一些内容。问题可能是什么?
This has to be very basic, but I don't see the problem. The program crashes whenever the following code block is executed. Analyzer reports a possible memory leak:
if (anImage) {
eventImageView.frame = defaultEventImageFrame;
UIImage *scaledImage = [anImage scaleToFitWithin:defaultEventImageFrame.size interpolationQuality:kCGInterpolationHigh];
eventImageView.backgroundColor = [UIColor colorWithPatternImage:scaledImage];
}
The message is -[UIImage release]: message sent to deallocated instance 0x1129d920*
Instance 0x1129d920 is scaledImage
I tried adding retains and releases, like this
if (anImage) {
eventImageView.frame = defaultEventImageFrame;
UIImage *scaledImage = [[anImage scaleToFitWithin:defaultEventImageFrame.size interpolationQuality:kCGInterpolationHigh] retain];
eventImageView.backgroundColor = [UIColor colorWithPatternImage:scaledImage];
[scaledImage release];
}
and still get the error message.
So I tried replacing the assignment with a copy, like this
if (anImage) {
eventImageView.frame = defaultEventImageFrame;
UIImage *scaledImage = [anImage copy];
eventImageView.backgroundColor = [UIColor colorWithPatternImage:scaledImage];
}
And the problem is gone.
Checking the scaleToFitWithin method, I see it returns an autoreleased object:
- (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];
}
So there is something about memory management that I'm not understanding. What is the problem likely to be?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题很可能是
scaleToFitWithin:interpolationQuality:
方法正在对之前已经autorelease
d 的对象调用autorelease
。如果您在调用缩放方法的同一方法中使用临时构造函数(例如+[UIImage imageWith...]
)初始化UIImage
,则可能会发生这种情况。当您使用[anImage copy]
时它起作用的原因是因为copy
构造函数的行为使得返回给您的对象已经具有retain 调用它(因此它的本地保留计数为 1,
autorelease
为零)。当前运行循环结束时发生的情况是:当前正在使用的自动释放池被耗尽,并且作为这两个
release
消息的一部分将被发送到UIImage.当第一个发送后,应用程序就会运行并在图像上调用dealloc,因为retainCount已减少到零。当发送第二个消息时,应用程序会引发异常,因为消息正在发送到先前已释放的对象。
尝试从
scaleToFitWithin:interpolationQuality:
方法中删除autorelease
消息。即使您的resizedImage:interpolationQuality:
方法返回一个 new 对象,您也应该只在该方法中调用autorelease
而不是缩放方法。The problem is most likely that the
scaleToFitWithin:interpolationQuality:
method is callingautorelease
on an object which has already previously beenautorelease
d. This can occur if you initialise theUIImage
using a temporary constructor, like+[UIImage imageWith...]
, earlier in the same method you call the scaling method from. The reason it works when you use[anImage copy]
is because the behaviour of thecopy
constructor is such that the object returned to you has already hadretain
called on it (so it has a local retain count of 1 and zeroautorelease
s).What happens at the end of the current run loop is: the autorelease pool which is currently in use is drained, and as a part of that two
release
messages will be sent to theUIImage
. When the first one is sent, the application then runs off and callsdealloc
on the image, because theretainCount
has decreased to zero. When the second one is sent, the application throws an exception because a message is being sent to an object which was previously deallocated.Try removing the
autorelease
message from thescaleToFitWithin:interpolationQuality:
method. Even if yourresizedImage:interpolationQuality:
method IS returning a new object, you should only be callingautorelease
in that method rather than the scaling method.似乎方法
resizedImage:interpolationQuality:
本身返回一个autoreleased
对象,并且您再次在 reutun 语句中自动释放它。只需从 return 语句中删除 autorelease,那么您就不必在
if 中保留/释放或复制返回的对象(anImage) {...}
块。It seems that the method
resizedImage:interpolationQuality:
itself returns anautoreleased
object and you are again autoreleasing it in the reutun statement. Just remove the autorelease from the return statement,Then you don't have to retain/release or copy the returned object in
if (anImage) {...}
block.