具有多个视图的 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_iPadUINavigationController,但从未释放它们。理想情况下,您应该自动释放 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的主要内容,如果未能解决你的问题,请参考以下文章

具有多个文本字段输入视图的多个选取器视图 Swift

具有多个视图的 UIViewcontroller

将具有多个子视图的视图截图为 wkwebview

创建具有多个对象/层的视图 [关闭]

具有自动布局的多个动态视图

如何在同一视图中使用具有不同数据源的多个选取器视图?