我在代码中弄清楚这个bug时遇到了很多麻烦。当我的应用程序启动时,我的主ViewController将openGL视图设置为它的view属性,位于:
- (void) loadView {
glView = [[EAGLView alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
[glView setAnimationFrameInterval: kAnimationFrameInterval];
[glView startAnimation];
UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *infoImage = [UIImage imageNamed:@"info.png"];
[infoButton setImage:infoImage forState:UIControlStateNormal];
[infoImage release];
infoButton.showsTouchWhenHighlighted = YES;
[infoButton addTarget:self action:@selector(showInfo) forControlEvents:UIControlEventTouchUpInside];
infoButton.frame = CGRectMake(0.0f, 0.0f, 48.0f, 48.0f);
infoButton.clipsToBounds = NO;
[glView addSubview:infoButton];
glView.contentMode = UIViewContentModeCenter;
self.view = glView;
}
并在
- (void)viewDidUnload {
glView = nil;
[super viewDidUnload];
}
当用户点击infoButton时,此视图控制器会显示一个模态视图控制器(从showInfo调用),该控制器具有一个tabBarController,其中包含更多viewControllers。
我的问题是,每当我在任何viewController中收到didReceiveMemoryWarning时,我的主Viewcontroller中的纹理都会按预期释放,但出于某种原因我无法重新加载它们,所以第一次发生时我得到的形状没有纹理,但如果用户再次点击infoButton并尝试返回,则应用程序崩溃。
所以我的问题是,我应该不惜一切代价保持glView活着,还是应该将它设置为nil并在我收到内存警告时释放它?我已经阅读了一些问题和Apple文档,说你应该重新创建这些东西。在didReceiveMemoryWarning中:
“这种方法的实现应该通过清除可以在以后重新创建(或从磁盘重新加载)的缓存数据对象来释放尽可能多的内存。”
我希望能够在用户返回到openGL视图之前执行此操作,以便UI不会滞后。任何帮助将不胜感激。
答案 0 :(得分:0)
首先,让我注意到调用
glView = nil;
不会向您的EAGLView发送一个版本,因此您在此处有内存泄漏(因为将其分配给self.view也会增加其保留计数器)。
您确定viewDidUnload
实际上已被调用吗?它应仅适用于当前未显示的视图。如果是这样,您是否可以添加有关崩溃/控制台日志类型等的更多信息?
考虑到泄漏的可能性,我会考虑应用程序因内存使用过多而被杀死。如果您在控制台日志末尾看到signal (0)
,则可以提供一个很好的提示。