MrH*_*Hen 3 memory iphone objective-c uiimage
出于某种原因,以下代码中的保留/释放行为让我感到困惑.
selectedImage = [UIImage imageNamed:@"icon_72.png"];
[selectedImage release];
Run Code Online (Sandbox Code Playgroud)
这应该打破但不会.为什么?我认为imageNamed自动释放本身意味着这里的释放是多余的,并且应该在自动释放发生时中断.
以下是.h和.m文件中与selectedImage相关的代码段:
@property (nonatomic, readonly) UIImage *selectedImage;
@synthesize delegate, selectedImage, spacerBottom, currentIndex;
Run Code Online (Sandbox Code Playgroud)
其他说明,这确实打破了:
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”.
Run Code Online (Sandbox Code Playgroud)
由于做这样的:
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”.
Run Code Online (Sandbox Code Playgroud)
所以做了以下内容:
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”.
Run Code Online (Sandbox Code Playgroud)
这样做:
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”.
Run Code Online (Sandbox Code Playgroud)
Jas*_*ien 11
-imageNamed:返回一个自动释放的图像,正如deanWombourne所说,将在未来的某个时间自动释放(确切的时间未定义).
它可能习惯于它自动释放的原因是-imageNamed还会缓存它返回的图像.缓存保留图像.
基本上,保留周期是这样的:
如果您不释放它,缓存将继续保留图像,直到它释放它,例如发生内存警告时.因此,当您使用imageNamed获取图像时,它将不会被释放,直到清除缓存.
希望这可以解决问题.
奇怪和奇怪,是的.但并非完全无法解释.这就是我认为正在发生的事情.
你是对的; imageNamed:返回一个自动释放的对象.这意味着它将在未来的某个时间发布,所以你马上调用它不会导致错误 - 释放不是通灵,它不知道自动释放池也会释放它!
如果您让代码运行,自动释放池最终会尝试再次释放它,然后您将收到您期望的错误.
你实际上已经回答了我们自己的问题 - 你说'应该在发生自动释放时破坏'这是绝对正确的,当自动释放发生时,它会破坏:)
其他示例会中断,因为您通过直接调用它们或执行足够的东西来触发autorelase池运行并为您调用release来强制释放.(您无法预测自动释放池何时运行,您可以知道在运行循环的某个时刻,自动释放的东西可能会被释放.)