首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UIImage imageNamed未正确自动释放

UIImage imageNamed未正确自动释放
EN

Stack Overflow用户
提问于 2010-05-28 15:15:50
回答 4查看 4.8K关注 0票数 3

由于某些原因,以下代码中的保留/发布行为让我完全困惑。

代码语言:javascript
复制
selectedImage = [UIImage imageNamed:@"icon_72.png"];
[selectedImage release];

这应该会中断,但是没有。为什么?我认为imageNamed自动发布了自己,这意味着这里的发布是多余的,在发生自动发布时应该会中断。

下面是与selectedImage相关的来自.h和.m文件的片段:

代码语言:javascript
复制
@property (nonatomic, readonly) UIImage *selectedImage;
@synthesize delegate, selectedImage, spacerBottom, currentIndex;

其他注意事项,此会破坏

代码语言:javascript
复制
selectedImage = [UIImage imageNamed:@"icon_72.png"];
[selectedImage release];
[selectedImage release];
//objc[55541]: FREED(id): message release sent to freed object=0x59245b0
//Program received signal:  “EXC_BAD_INSTRUCTION”.

正如所做的那样,是这样的:

代码语言:javascript
复制
selectedImage = [UIImage imageNamed:@"icon_72.png"];
[selectedImage release];
[selectedImage autorelease];
//objc[55403]: FREED(id): message autorelease sent to freed object=0x59b54c0
//Program received signal:  “EXC_BAD_INSTRUCTION”.

因此,执行如下:

代码语言:javascript
复制
selectedImage = [UIImage imageNamed:@"icon_72.png"];
[selectedImage autorelease];
[selectedImage release];
//objc[55264]: FREED(id): message release sent to freed object=0x592c9a0
//Program received signal:  “EXC_BAD_INSTRUCTION”.

所以做了这个:

代码语言:javascript
复制
selectedImage = [UIImage imageNamed:@"icon_72.png"];
[selectedImage autorelease];
[selectedImage autorelease];
//objc[55635]: FREED(id): message release sent to freed object=0x5b305d0
//Program received signal:  “EXC_BAD_INSTRUCTION”.
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-05-28 16:02:59

-imageNamed:返回一个自动释放的映像,正如deanWombourne所说,它将在将来的某个时候自动发布(确切的时间还没有定义)。

它之所以没有在您习惯的时候自动发布,可能是因为-imageNamed也缓存它返回的图像。缓存将保留图像。

因此,本质上,保留周期是这样的:

it).

  • -imageNamed:调用,
  • 系统分配和init是一个映像-保留计数= 1;
  • 系统缓存图像

在映像上调用

  • --保留计数应该是0,并且对象应该是将来某个点(在运行循环结束时),自动释放池应该释放映像,并且会崩溃,因为您已经过度释放了它。

如果不释放它,缓存将继续保留图像,直到它释放为止,例如,当发生内存警告时。因此,当您使用imageNamed获得一个映像时,它不会被释放,直到缓存被清除。

希望这能把事情弄清楚。

票数 11
EN

Stack Overflow用户

发布于 2010-05-28 15:19:07

奇怪又无聊,是的。但不是完全莫名其妙。这就是我认为正在发生的事情。

是正确的;imageNamed:返回一个自动释放的对象。这意味着它将在将来的某个时候发布,所以您立即调用它的发布不会导致错误-发布不是灵媒,它不知道自动释放池也会发布它!

如果您让代码运行,那么自动发布池最终会再次尝试释放它,然后您将得到您期望的错误。

您实际上已经回答了我们自己的问题--您说‘当自动释放发生时应该中断’,这是绝对正确的,当自动释放发生时,它将中断:)

其他示例之所以失败,是因为您通过直接调用或执行足够多的操作来强制发布,从而触发了autorelase池并为您调用release。(您无法预测自动释放池何时运行,您只需知道在运行循环的某个时候,自动释放的东西就会被释放。)

票数 8
EN

Stack Overflow用户

发布于 2010-05-28 16:24:39

你说“这应该打破”

代码语言:javascript
复制
selectedImage = [UIImage imageNamed:@"icon_72.png"];
[selectedImage release];

你错了。

如果UIImage是那种类的例子的话,它可能会崩溃,我会写并且学着用可可书写作,但是我们没有写它,所以我们不应该猜测它的实现。

UIImage如何工作是一个实现细节,而不是您关心的问题。你所知道的是,如果你遵守规则的话,你应该可以期待它发挥作用,我相信现在被称为NARC,而你在这里还没有这样做。如果使用不当,任何对象都不能保证“破坏”。当您使用对象时,不能指望它们被释放--这不是内存管理契约的一部分。

并不是所有Apple的对象都像教科书类/实例一样工作--实际上,对象可能被缓存、重用、回收,甚至根本不是对象。

别担心,遵守规矩。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2930204

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档