具有多个视图的 UIViewcontroller
Posted
技术标签:
【中文标题】具有多个视图的 UIViewcontroller【英文标题】:UIViewcontroller with multiple views 【发布时间】:2012-06-11 15:58:52 【问题描述】:该项目目前有一个名为“Dashboard”的 UIviewController,它充当所有应用程序的主视图。这个主视图由上面的两个子视图组成,有点像拆分视图。主(左视图)的左侧有多个按钮。右侧(右视图)将显示左侧所选按钮的内容。
当按下按钮时,它将创建一个新的视图实例,显示如下:
vcMySchedule_iPad *vcSchedule = [[vcMySchedule_iPad alloc] initWithNibName:@"vcMySchedule_iPad" bundle:nil];
ncDashboard = [[UINavigationController alloc] initWithRootViewController:vcSchedule];
ncDashboard.navigationBar.barStyle = UIBarStyleBlackOpaque;
ncDashboard.view.frame = self.vwRightPanel.bounds;
[self.vwRightPanel addSubview:ncDashboard.view];
问题是当按下另一个按钮时,它会显示另一个视图,但是前一个调用的内存仍然存在,并且前一个视图的dealloc永远不会被调用。
我没有使用拆分视图,因为左侧有一个按钮,当按下时它将左侧移动到左侧,右侧将左侧移动以完全查看。
有没有办法解决这个问题?
更新了一些图片...
主要(MainViewController):
按课程目录:
vcCourseCatalog_iPad *vcCourse = [[vcCourseCatalog_iPad alloc] initWithNibName:@"vcCourseCatalog_iPad" bundle:nil];
ncDashboard = [[UINavigationController alloc] initWithRootViewController:vcCourse];
ncDashboard.navigationBar.barStyle = UIBarStyleBlackOpaque;
ncDashboard.view.frame = self.vwRightPanel.bounds;
[self.vwRightPanel addSubview:ncDashboard.view];
当从表格中选择一行时,它会显示详细信息,如果用户按下按钮,则视图会最大显示。
我想我可能一直认为新观点是错误的。释放的对象在哪里?
【问题讨论】:
【参考方案1】:如果没有更多信息,我无法给出可靠的建议,但请检查以下内容:
-
您在使用 ARC 吗?如果不是,请记住您必须在释放某些内容之前显式释放所有引用。
您是否在其他任何地方保留对子视图的引用?如果您仍在某处引用它(尤其是在 ARC 中),它会一直存在。循环引用在这里是邪恶的。
在将子视图替换为新视图之前,是否要从它的父视图中删除它?您会惊讶于如此简单的事情发生的频率。
编辑:
针对以下问题,关于您不使用 ARC,很明显 1) 是您的问题。您没有发布参考。在这种情况下,这里似乎很明显:
vcCourseCatalog_iPad *vcCourse = [[vcCourseCatalog_iPad alloc] initWithNibName:@"vcCourseCatalog_iPad" bundle:nil]; ncDashboard = [[UINavigationController alloc] initWithRootViewController:vcCourse];
ncDashboard.navigationBar.barStyle = UIBarStyleBlackOpaque;
ncDashboard.view.frame = self.vwRightPanel.bounds;
[self.vwRightPanel addSubview:ncDashboard.view];
您正在分配vcCourseCatalog_iPad
和UINavigationController
,但从未释放它们。理想情况下,您应该自动释放 vcCourseCatalog_iPad,并在更换导航控制器时释放它。
您的代码应该如下所示:
vcCourseCatalog_iPad *vcCourse = [[[vcCourseCatalog_iPad alloc] initWithNibName:@"vcCourseCatalog_iPad" bundle:nil] autorelease];
if(ncDashboard)
//do any sort of removal from views here
//[ncDashboard.view removeFromSuperview];
[ncDashboard release];
ncDashboard = [[UINavigationController alloc] initWithRootViewController:vcCourse];
ncDashboard.navigationBar.barStyle = UIBarStyleBlackOpaque;
ncDashboard.view.frame = self.vwRightPanel.bounds;
[self.vwRightPanel addSubview:ncDashboard.view];
【讨论】:
我没有使用 ARC。我正在使用主视图中名为“removeViewsFromRight”的方法删除视图。由于用户可以按左窗格中的任何按钮,我必须从主窗格中删除视图。 在这种情况下它非常简单——正如我在 1) 中提到的那样,您在创建它们之后不会发布它们。创建 vcCourseCatalog_iPad 时,它的保留计数为 1。然后将其传递给 UINavigationController,它在内部存储对它的引用,将保留计数增加到 2。当 UINavigationController 被释放时,它释放 vcCourseCatalog_iPad,给它一个保留计数 1,你永远无法摆脱它,因为没有对它的引用。如果您自动释放 vcCourseCatalog_iPad,那么它将被正确处理。 感谢您的所有帮助。知道我理解得更好。【参考方案2】:除了 CrimsonDiego 的回答之外,我建议您在文件中使用以下几行:
在.h
文件中:
@property (nonatomic, retain) UIView *ncDashBoard;
在.m
文件中:
@synthesize ncDashBoard = _ncDashBoard;
然后从那时起只使用_ncDashBoard
。这是为了确保正确设置保留计数。
【讨论】:
以上是关于具有多个视图的 UIViewcontroller的主要内容,如果未能解决你的问题,请参考以下文章