我有一个我在nib文件中设置的UIImageView。我从互联网上下载图像并将图像设置为UIImageView。当我发布它时保留计数2?如果我只使用1个版本,它将不会显示任何内存泄漏,但我可以在“仪器分配”中看到它永远不会被释放。当我像下面两次发布UIImageView时,它运行良好。但是我永远不应该发布它两次?!?!
标题中的:
IBOutlet UIImageView *background;
<。>在.m中加载图片:
/* Load Image code */
id path = [NSString stringWithFormat:@"http://www.image.com/aImage.jpg"];
NSURL *url = [NSURL URLWithString:path];
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSData* urlData = [[NSData alloc] initWithContentsOfURL:url];
[background setImage:[UIImage imageWithData:urlData]];
[urlData release];
[pool release];
在dealloc函数中:
- (void)dealloc {
NSLog(@"Backgroud count: %i",[background retainCount]); // Prints 2
[background release];
[background release]; // Does not "leak" if i have 2x release
[super dealloc];
}
这是使用UIImageView背景的唯一代码。
编辑:
我忘了提到的是我在这样的for循环中运行这段代码。但这个for循环只执行一次!但这没关系?
for (id theKey in dictionary) {
/* Load Image code above is here */
}
答案 0 :(得分:3)
我相信我已经弄清楚了问题是什么。 Apple建议您通过IBOutlet
保留连接的对象(在本例中为图像视图)。你说你还没有这样做,但你应该遵循Apple的建议。你应该在iphonedevsdk.com forum post中概述你应该解决这个问题的原因,该问题链接到一个全神贯注的大书呆子牧场blog post。
在iOS上,nib加载机制使用setter,如果你的插座有一个,但如果没有,它使用键值编码;具体来说,它使用setValue:forKey:
,保留值(这是记录在案的,但有点意外)。作为视图控制器顶视图子视图的图像视图由该视图保留。它也由此键值设置程序保留。因此,您不知道,您的对象有两个对图像视图的引用。 Apple提出了保留属性建议,以便您了解视图是否被保留。
你仍然不应该担心保留计数,但你应该做以下两件事之一:将此IBOutlet
保留为保留属性并在中释放 {{ 1}}和viewDidUnload
(虽然每次只有一次!),或遵循BNR的建议并明确指定属性:
dealloc
在这种情况下,您无需自行发布。在这两种情况下,请确保@property (assign, nonatomic) IBOutlet UIImageView *background;
属性访问者。
Don't look at retain count,如果没有检测到泄漏,那么不要担心。 UIKit框架可能会因您不知情的原因而保留该视图。
此外,如果@synthesize
不是保留属性:
background
并且你在xib中创建它,你不应该发布 at all ,因为你不拥有它。也就是说,你不是responsible for its memory;为您提供责任的操作包括:在对象上调用@property (retain) IBOutlet UIImageView *background;
,或使用名称以retain
,alloc
,copy
或{{开头的方法创建对象1}}。
答案 1 :(得分:0)
我对nib文件了解不多,我曾经按照下面的说法进行操作
background=[[UIImageView alloc] initWithFrame:CGRectMake(0,0,320,480)]; //Now the reatin count is 1 [background setImage:[UIImage imageWithData:urlData]]; [someView addSubview:background]; //Now the ratainCount will be 2 since we added the imageview to the superview [background release]; //i will release immediately so the retain count drops to 1 . . . //in dealloc or viewDidDisaaper i will remove the imageview from its superview //then the retainCount will become 0 and the instance will be deallocated. //it works for we without any memory leakage [background removeFromSuperview];