UIImageView的保留计数很奇怪,我需要释放两次以避免泄漏



我得到了一个在笔尖文件中设置的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 */
}
我相信

我已经弄清楚了问题所在。Apple 建议您保留通过 IBOutlet s(在本例中为图像视图)连接到的对象。你说你没有这样做,但你应该遵循苹果的建议。您应该在一篇关于此问题的 iphonedevsdk.com 论坛帖子中概述了您应该的原因,该文章链接到一篇 Big Nerd Ranch 博客文章,该文章列出了所有内容。

在 iOS 上,如果您的插座有 setter,笔尖加载机制会使用资源库,如果没有,它会使用键值编码;具体来说,它使用 setValue:forKey:它保留了值(这是有记录的,但有些出乎意料)。图像视图(即视图控制器顶视图的子视图)由该视图保留。此键值设置过程也会保留它。因此,您不知道,您的对象有两个对图像视图的引用。Apple 提出保留属性建议,以便您知道视图正在保留。

您仍然不必担心保留计数本身,但您应该做以下两件事之一:将此IBOutlet保留属性,并在viewDidUnloaddealloc中释放它(不过,每个都只有一次!),或者遵循 BNR 的建议并明确分配属性:

@property (assign, nonatomic) IBOutlet UIImageView *background;

在这种情况下,您不必自己释放它。在这两种情况下,请确保@synthesize属性访问器。

<小时 />

以前:

不要看保留计数,如果没有检测到泄漏,那就不用担心了。UIKit 框架可能出于您不知道的原因保留视图。

此外,如果background不是保留属性:

@property (retain) IBOutlet UIImageView *background;

你在 XIB 中创建它,你根本不应该发布它,因为你不拥有它。也就是说,您不对它的记忆负责;赋予您该责任的操作是:在对象上调用retain,或使用名称以 alloccopymutableCopynew 开头的方法创建对象。

我对nib文件了解不多,我曾经像下面这样关注

 background=[[UIImageView alloc] initWithFrame:CGRectMake(0,0,320,480)];  现在雷丁计数为 1 [background setImage:[UIImage imageWithData:urlData]];  [某些视图添加子视图:背景];  现在 ratainCount 将是 2,因为我们将图像视图添加到超级视图  [后台发布]; 我将立即释放,因此保留计数降至 1 . . .在 dealloc 或 viewDidDisaaper 中,我将从其超级视图中删除图像视图则保留计数将变为 0,并且实例将被解除分配。它适用于我们,没有任何内存泄漏[背景从超级视图中删除];

最新更新