最近创建的对象的大量保留计数。 Objective-C

Posted

技术标签:

【中文标题】最近创建的对象的大量保留计数。 Objective-C【英文标题】:Large retain count with a recent created object. Objective-C 【发布时间】:2012-01-25 17:49:00 【问题描述】:

我遇到了一个奇怪的情况,即按下按钮时我正在加载的视图控制器的保留计数过多。

这是代码:

-(IBAction)new

    if (!viewSpace)
        viewSpace = [[ViewSpace alloc] initWithNibName:@"ViewSpace" bundle:nil];

    viewSpace.delegate = self;

    viewSpace.view.frame = CGRectMake(0, 0, viewSpace.view.frame.size.width, viewSpace.view.frame.size.height);

    [self presentModalViewController:viewSpace animated:YES];

    NSLog(@"Count Retain: %d",[viewSpace retainCount]);


-(void)viewSpaceWasDissmissed:(id)sender

    [self dismissModalViewControllerAnimated:YES];
    [viewSpace release];    
    NSLog(@"Count Retain: %d",[viewSpace retainCount]);

IBAction New 首次执行时,刚创建时的保留计数为 5。 (必须为 1)。

当必须卸载 ViewSpace 对象时,调用 viewSpaceWasDismissed 函数以移除模态视图并释放前一个对象。

问题是retain count永远不会达到0,ViewSpace的dealloc方法永远不会被调用导致内存泄漏。

我的问题是最近创建的 ViewController 怎么可能有 5 个保留?我确保以前从未创建过。

谢谢。

【问题讨论】:

retainCount 完全没用。你在浪费时间去想它。 是的,但问题是永远无法达到 ViewSpace 对象的 dealloc。这会导致我的应用内存使用率过高并崩溃。 @bbum 你是在看retainCount 标签的RSS 提要,还是什么? ;) @user1132003 然后你需要弄清楚额外保留来自哪里,retainCount 不会告诉你。使用分配工具并打开保留事件跟踪。然后查看所有的保留事件并找出哪个没有被release 平衡。 @abizem 是的——它提供了一点娱乐。我完全承认自己很容易被逗乐。 【参考方案1】:

Cocoa 可能出于自身原因在内部保留了 4 次视图控制器。这不是问题。

更一般地,-retainCount 方法由于这样的原因是无用的,你永远不应该调用它。它不会帮助你,它会让你感到困惑。

为了调试您的泄漏,我建议使用泄漏工具,检查对象,并分析每个保留和释放的来源,以确定是否有任何错误。

【讨论】:

【参考方案2】:

查看-retainCount 的文档。我相信它说您不应该自己调用它 - 您只需要处理您引起的任何保留,并且不要担心“实际”保留计数。

【讨论】:

【参考方案3】:

你在这里做错了两件事:

    当前视图控制器保留模态呈现的视图控制器,并在它被关闭时释放它。所以viewSpace出现后你应该释放它,你不需要dismissModalViewController方法中的释放消息。顺便说一句,ViewSpace 对于视图控制器来说是一个糟糕的名字。在我知道它是视图控制器之前,我必须阅读您将其作为视图控制器呈现的那一行。我认为ViewSpaceController 是一个更具描述性的名称。 您使用的是retainCount,这总是一个坏主意。重要的是,在您的 new 方法中,您创建了一个拥有的对象(使用 alloc),并且您通过发布来平衡该所有权(或者至少当您进行我在第 1 点中建议的更正时您会这样做)就是这样。您获得了一个对象的所有权并释放了它。 retainCount 方法绝对不会告诉你任何对你有用的东西。不要这样做。只需平衡所有权与发布,这才是最重要的。

【讨论】:

我按照建议申请了。但问题仍然存在。从未达到 dealloc 方法,我遇到了内存使用问题。 retainCount 不会帮助您找到泄漏点。通过仪器运行您的应用程序,看看您的视图控制器到底发生了什么。 我做到了,我删除了保留计数,并且我正在使用工具。问题是每次加载和卸载 ViewSpace 对象时,内存都会增加 1,30 Mb。在几次打开/关闭操作后,应用程序崩溃。 如果dealloc方法用于清理对象,并且当retain count达到零时会自动调用dealloc,为什么我必须在创建而不是在相同的方法中调用release不同的方法?在用户关闭对象 ViewSpace 之前,该对象必须处于活动状态? 你需要释放它,因为它在呈现时被当前视图控制器保留,并且当前视图控制器在它被关闭时也释放它。这就是为什么你需要在我在第 1 点中解释的相同函数中平衡你的 alloc 和 init。【参考方案4】:

我不是 100% 确定每个计数,但这里有一些:

实例化 - 1 NIB - 1+ 强大的属性 (1+)

此外,将其列为强属性的任何属性(在 ARC 中)。 我注意到,当您启动一个 nib 并在 nib 设计中使用控制器的组件时,它会增加控制器实例上的引用计数(以一种强的方式)。

【讨论】:

ARC 不适用于此代码。在 ARC 下不允许调用 releaseretainCount

以上是关于最近创建的对象的大量保留计数。 Objective-C的主要内容,如果未能解决你的问题,请参考以下文章

在 Objective-C 中保留计数和工厂方法

为啥在启用 ARC 的项目中不需要维护保留计数

如何找到对象的保留计数? [复制]

有人能告诉我在objective-c中保留和释放到底做了啥吗?

Objective-C 内存管理retain和release

iOS 内存管理