gpt4 book ai didi

objective-c - 在 NSWindow 中呈现不同 NSViewController 的正确方法

转载 作者:行者123 更新时间:2023-12-03 16:40:46 24 4
gpt4 key购买 nike

我正在开发一个单一 NSWindow 的应用程序,单击窗口内的按钮将显示一个 NSViewController,并且该 Controller 中存在一个按钮,该按钮将显示一个不同的NSViewController。我知道如何交换窗口中的 View ,但在尝试使用多个 View Controller 执行此操作时遇到了问题。我已经解决了该问题,但我不认为我正在以适当的方式完成此行为。

我最初在AppDelegate中定义了一个方法:

- (void)displayViewcontroller:(NSViewController *)viewController {
BOOL ended = [self.window makeFirstResponder:self.window];
if (!ended) {
NSBeep();
return;
}
[self.box setContentView:viewController.view];
}

我为 AppDelegate 的 NSButton 设置了一个目标/操作,在这里我调用该方法来显示新的 View Controller :

- (IBAction)didTapContinue:(NSButton *)sender {
NewViewController *newVC = [[NewViewController alloc] init];
[self displayViewcontroller:newVC];
}

这确实有效 - 它呈现了新 View Controller 的 View 。但是,如果我随后单击该 View 中的任何按钮,该按钮设置了驻留在其 View Controller 类中的目标/操作,则应用程序会立即崩溃。

要解决此问题,我必须将 didTapContinue: 更改为以下内容:

- (IBAction)didTapContinue:(NSButton *)sender {
NewViewController *newVC = [[NewViewController alloc] init];
[self.viewControllers addObject:newVC];
[self displayViewcontroller:[self.viewControllers lastObject]];
}

首先,您能解释一下为什么可以解决这个问题吗?似乎与 Controller 在内存中“保留”的方式有关,但我并不肯定。

我的问题是,如何设置才能从任何 View Controller 中交换 View ?我计划获取对 AppDelegate 的引用,并使用我刚刚在该类中实例化的新 Controller 调用 displayViewcontroller:,但这会导致崩溃。我需要首先将其存储在数组中,然后将该引用发送到方法中。这是一种有效的方法吗 - 将 viewControllers 数组公开,然后使用 lastObject 调用该方法,或者应该如何设置?

最佳答案

代码中有趣的是,每次调用 IBAction 时都会分配/初始化一个新的 View Controller 。每次调用 IBAction 方法时,您的 View 可能都是全新的,但我认为您想要显示的 View 数量有限。据我所知,这使得您的观点只有在您的 IBAction 方法很长的情况下才能存在。 View 仍然存在,是因为您尚未刷新它。但是,在 View Controller 内调用不再位于堆中的方法(因为您离开了 IBAction 方法,并且所有本地对象(例如您的 View Controller 都从堆中获取,而不是 ARC))会使应用程序崩溃,因为您引用了未使用或被其他东西使用的内存空间。

为什么当您将 View 添加到 viewcontrollers 数组时应用程序可以工作?我假设这个数组是一个已经在 AppDelegate 中启动的数组,现在您将具有强引用计数的 View Controller 添加到 viewcontrollers 数组中。当您离开 IBAction 方法时, View Controller 仍然具有强引用,并且 ARC 不会释放 View Controller 。

这是正确的方法吗?嗯,它有效。我不认为这被认为是非常好的编程,因为您不会在方法中分配/初始化一个在离开该方法后需要保持事件状态的对象。更好的做法是在 AppDelegate 的 init、awakeFromNIB 或 windowDidLoad 方法中的某个位置分配和初始化 View Controller 。当前解决方案的问题在于,您正在创建无限的 View Controller 数组,而您只使用最后一个。在某个地方,您的程序会感受到这个非常长的相当重的对象( View Controller )数组的负担,并且会耗尽内存。

希望这有帮助。

顺便说一句,这与您使用 Mavericks 还是 Yosemite 无关。我正在考虑 Storyboard解决方案,但这不能回答您的问题。

亲切的问候,Mac用户T

关于objective-c - 在 NSWindow 中呈现不同 NSViewController 的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29178982/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com