ARC&我的应用中的内存管理

时间:2013-06-21 10:51:01

标签: objective-c memory-management automatic-ref-counting release-management retaincount

修改

我发现我的屏幕不会因为保留RefCt而没有,但我的问题是为什么不是RefCt 0?我只是创建,添加和删除视图。还添加了一个仪器的screendump:

Screendump of Instruments

所以你在开始时看到

Malloc 1 initwithframe,保留:2 initwithframe,发布:1 - [UIView(内部)_addSubview:定位:relativeTo:],保留:2 Quartzcore CALAyer layoutSublayers,保留:3 Quartzcore CALAyer layoutSublayers,发布:2 然后在我的代码中删除此视图,removeFromSuperView:1

有人可以解释一下:

 -[UIView(Internal) _addSubview:positioned:relativeTo:], retain : 2

行?我认为这就是为什么我的观点仍然有一个RefCt。

END

我试图清理我的代码并最终加速我的应用程序,但我不认为我真的得到了整个内存管理的事情。基本上我的应用程序有一个对用户可见的视图,但它可以切换到不同的视图,具体取决于用户在菜单中选择的内容。现在我认为最大的逻辑是,一次只能分配一个视图并占用内存空间,当用户选择另一个视图时,应该释放当前视图并分配所选视图。我在选择新视图时尝试通过这样做来创建它:

- (void)removeMenus {
    @autoreleasepool {
        for (UIView *view in container.subviews) {
            NSLog(@"View to be removed: %@", view);
            [view removeFromSuperview];
        }
    }
}

让我们说用户选择再次显示启动屏幕。这段代码将运行:

- (void)createStartScreen {
    if (startScreen == nil) {
        startScreen = [[StartScreen alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
        startScreen.delegate = self;
        startScreen.layer.shadowColor = [[UIColor blackColor] CGColor];
        startScreen.layer.shadowOffset = CGSizeMake(0.0f, 0.0f);
        startScreen.layer.shadowRadius = 5.0f;
        startScreen.layer.shadowOpacity = 1.0f;
    }
}

我在那里放了一个断点,发现开始屏幕不是零,而我认为它应该是因为我从superview中删除了它(也尝试将那个var的指针弄出来)。如果我理解这一点,启动屏幕的保留计数不为零吗?我也在使用ARC,所以我认为ARC可以很好地处理这个问题。

释放不再对用户可见的视图以保存内存的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

如果您希望更多地了解阻止视图发布的内容,您应该使用Instruments的分配模板配置您的应用。这将告诉您每个保留和释放的调用站点,包括ARC和系统框架执行的那些。如果您的视图是从XIB文件实例化的,那么在一定程度上,系统框架会控制它们的生命周期。

我能提供的下一段圣人建议就是不要再考虑现在的绝对保留计数。只是假装-retainCount方法不存在。真。我不是在开玩笑。其他权力远远超过我的人解释了为什么保留计数没有用的细节,所以如果你不理解我的话,请阅读this

所有这一切,我没有足够的信息可以确定,但通常过多的内存使用不是由于一个或两个尚未发布的视图。仪器可以让您了解真正的问题。

答案 1 :(得分:1)

这取决于ivar startScreen是什么。如果在视图控制器中将startScreen定义为强ivar,则在分配后它将具有1的引用计数,并且在视图层次结构中将其设置为子视图后引用的引用数为2。然后,从超级视图中删除视图只会将refcount减少到1,并且你必须明确地将变量设置为nall来解除它。

另一个选项是您的视图在Storyboard或XIB文件中定义,并通过插座连接到视图控制器。在这种情况下,您的视图ivar必须设置为弱变量,因为它已被其他人强烈保留。

了解强弱限定符here之间的差异。

最后一件事 - 为了更好的可读性,在lazy实例化的变量上定义属性是一种常见的约定,然后将你在createStartScreen内编写的代码放在重写的getter方法中。