修改
我发现我的屏幕不会因为保留RefCt而没有,但我的问题是为什么不是RefCt 0?我只是创建,添加和删除视图。还添加了一个仪器的screendump:
所以你在开始时看到
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。
我试图清理我的代码并最终加速我的应用程序,但我不认为我真的得到了整个内存管理的事情。基本上我的应用程序有一个对用户可见的视图,但它可以切换到不同的视图,具体取决于用户在菜单中选择的内容。现在我认为最大的逻辑是,一次只能分配一个视图并占用内存空间,当用户选择另一个视图时,应该释放当前视图并分配所选视图。我在选择新视图时尝试通过这样做来创建它:
- (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可以很好地处理这个问题。
释放不再对用户可见的视图以保存内存的正确方法是什么?
答案 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方法中。